From 7fcc88654fa81ba6bd511f62ef6b0223f90d7fae Mon Sep 17 00:00:00 2001 From: facebook-github-bot Date: Thu, 19 Dec 2024 14:01:10 +0000 Subject: [PATCH] Deploy website - based on 6ce07689df2023419f2ed8f0fd44fab6bc007aa7 --- 404.html | 2 +- ...e4035.b69a3096.js => 041e4035.e204036c.js} | 2 +- assets/js/223037ba.2aa7902c.js | 1 - assets/js/223037ba.890494e4.js | 1 + ...eae25.904d52c1.js => 8fdeae25.5a49904a.js} | 2 +- assets/js/c359af60.1278ce61.js | 1 - assets/js/c359af60.87765c92.js | 1 + ...n.bf22b583.js => runtime~main.f2ef44c5.js} | 2 +- .../index.html | 2 +- .../17/collaboration-with-spotify/index.html | 2 +- .../07/mobileatscale-london-talk/index.html | 2 +- .../06/23/first-opensourceversary/index.html | 2 +- blog/2016/08/30/curryon-rome-talk/index.html | 2 +- blog/2016/11/28/atscale16/index.html | 2 +- .../10/20/ocamlformat-released/index.html | 2 +- blog/archive/index.html | 2 +- blog/index.html | 2 +- docs/1.1.0/about-Infer/index.html | 2 +- docs/1.1.0/absint-framework/index.html | 2 +- docs/1.1.0/all-issue-types/index.html | 2 +- .../analyzing-apps-or-projects/index.html | 2 +- .../index.html | 2 +- docs/1.1.0/checker-biabduction/index.html | 2 +- docs/1.1.0/checker-bufferoverrun/index.html | 2 +- .../index.html | 2 +- .../checker-config-impact-analysis/index.html | 2 +- docs/1.1.0/checker-cost/index.html | 2 +- .../checker-dotnet-resource-leak/index.html | 2 +- docs/1.1.0/checker-eradicate/index.html | 2 +- .../checker-fragment-retains-view/index.html | 2 +- docs/1.1.0/checker-immutable-cast/index.html | 2 +- docs/1.1.0/checker-impurity/index.html | 2 +- .../index.html | 2 +- docs/1.1.0/checker-linters/index.html | 2 +- .../checker-litho-required-props/index.html | 2 +- docs/1.1.0/checker-liveness/index.html | 2 +- docs/1.1.0/checker-loop-hoisting/index.html | 2 +- docs/1.1.0/checker-printf-args/index.html | 2 +- docs/1.1.0/checker-pulse/index.html | 2 +- docs/1.1.0/checker-purity/index.html | 2 +- docs/1.1.0/checker-quandary/index.html | 2 +- docs/1.1.0/checker-racerd/index.html | 2 +- .../checker-resource-leak-lab/index.html | 2 +- docs/1.1.0/checker-self-in-block/index.html | 2 +- docs/1.1.0/checker-siof/index.html | 2 +- docs/1.1.0/checker-starvation/index.html | 2 +- docs/1.1.0/checker-topl/index.html | 2 +- docs/1.1.0/checker-uninit/index.html | 2 +- docs/1.1.0/getting-started/index.html | 2 +- docs/1.1.0/hello-world/index.html | 2 +- docs/1.1.0/infer-workflow/index.html | 2 +- docs/1.1.0/internal-API/index.html | 2 +- docs/1.1.0/man-infer-analyze/index.html | 2 +- docs/1.1.0/man-infer-capture/index.html | 2 +- docs/1.1.0/man-infer-compile/index.html | 2 +- docs/1.1.0/man-infer-debug/index.html | 2 +- docs/1.1.0/man-infer-explore/index.html | 2 +- docs/1.1.0/man-infer-help/index.html | 2 +- docs/1.1.0/man-infer-report/index.html | 2 +- docs/1.1.0/man-infer-reportdiff/index.html | 2 +- docs/1.1.0/man-infer-run/index.html | 2 +- docs/1.1.0/man-infer/index.html | 2 +- docs/1.1.0/man-pages/index.html | 2 +- .../index.html | 2 +- docs/1.1.0/steps-for-ci/index.html | 2 +- docs/1.1.0/support/index.html | 2 +- docs/1.1.0/versions/index.html | 2 +- docs/about-Infer/index.html | 2 +- docs/absint-framework/index.html | 2 +- docs/all-categories/index.html | 2 +- docs/all-checkers/index.html | 2 +- docs/all-issue-types/index.html | 2 +- docs/analyzing-apps-or-projects/index.html | 2 +- .../index.html | 2 +- docs/checker-biabduction/index.html | 2 +- docs/checker-bufferoverrun/index.html | 2 +- .../checker-config-impact-analysis/index.html | 2 +- docs/checker-cost/index.html | 2 +- docs/checker-datalog/index.html | 2 +- docs/checker-fragment-retains-view/index.html | 2 +- docs/checker-impurity/index.html | 2 +- .../index.html | 2 +- docs/checker-lineage/index.html | 2 +- docs/checker-litho-required-props/index.html | 2 +- docs/checker-liveness/index.html | 2 +- docs/checker-loop-hoisting/index.html | 2 +- .../index.html | 2 +- docs/checker-printf-args/index.html | 2 +- docs/checker-pulse/index.html | 2 +- docs/checker-purity/index.html | 2 +- docs/checker-quandary/index.html | 2 +- docs/checker-racerd/index.html | 2 +- docs/checker-resource-leak-lab/index.html | 2 +- docs/checker-scope-leakage/index.html | 2 +- docs/checker-self-in-block/index.html | 2 +- docs/checker-sil-validation/index.html | 2 +- docs/checker-siof/index.html | 2 +- docs/checker-starvation/index.html | 2 +- docs/checker-topl/index.html | 2 +- docs/getting-started/index.html | 2 +- docs/hello-world/index.html | 2 +- docs/infer-workflow/index.html | 2 +- docs/internal-API/index.html | 2 +- docs/man-infer-analyze/index.html | 2 +- docs/man-infer-capture/index.html | 2 +- docs/man-infer-compile/index.html | 2 +- docs/man-infer-debug/index.html | 2 +- docs/man-infer-explore/index.html | 2 +- docs/man-infer-help/index.html | 2 +- docs/man-infer-report/index.html | 2 +- docs/man-infer-reportdiff/index.html | 2 +- docs/man-infer-run/index.html | 2 +- docs/man-infer/index.html | 2 +- docs/man-pages/index.html | 2 +- docs/next/about-Infer/index.html | 2 +- docs/next/absint-framework/index.html | 2 +- docs/next/all-categories/index.html | 4 +- docs/next/all-checkers/index.html | 2 +- docs/next/all-issue-types/index.html | 12 +- .../analyzing-apps-or-projects/index.html | 2 +- .../index.html | 2 +- docs/next/checker-biabduction/index.html | 2 +- docs/next/checker-bufferoverrun/index.html | 2 +- .../checker-config-impact-analysis/index.html | 2 +- docs/next/checker-cost/index.html | 2 +- .../checker-fragment-retains-view/index.html | 2 +- docs/next/checker-impurity/index.html | 2 +- .../index.html | 2 +- docs/next/checker-lineage/index.html | 2 +- .../checker-litho-required-props/index.html | 2 +- docs/next/checker-liveness/index.html | 2 +- docs/next/checker-loop-hoisting/index.html | 2 +- .../index.html | 2 +- docs/next/checker-pulse/index.html | 3 +- docs/next/checker-purity/index.html | 2 +- docs/next/checker-racerd/index.html | 2 +- .../next/checker-resource-leak-lab/index.html | 2 +- docs/next/checker-scope-leakage/index.html | 2 +- docs/next/checker-self-in-block/index.html | 2 +- docs/next/checker-sil-validation/index.html | 2 +- docs/next/checker-siof/index.html | 2 +- docs/next/checker-starvation/index.html | 3 +- .../index.html | 2 +- docs/next/checker-topl/index.html | 2 +- docs/next/getting-started/index.html | 2 +- docs/next/hello-world/index.html | 2 +- docs/next/infer-workflow/index.html | 2 +- docs/next/internal-API/index.html | 2 +- docs/next/man-infer-analyze/index.html | 2 +- docs/next/man-infer-capture/index.html | 2 +- docs/next/man-infer-compile/index.html | 2 +- docs/next/man-infer-debug/index.html | 2 +- docs/next/man-infer-explore/index.html | 2 +- docs/next/man-infer-help/index.html | 2 +- docs/next/man-infer-report/index.html | 2 +- docs/next/man-infer-reportdiff/index.html | 2 +- docs/next/man-infer-run/index.html | 2 +- docs/next/man-infer/index.html | 2 +- docs/next/man-pages/index.html | 2 +- .../index.html | 2 +- docs/next/steps-for-ci/index.html | 2 +- docs/next/support/index.html | 2 +- docs/next/suppressions/index.html | 2 +- docs/next/versions/index.html | 2 +- .../index.html | 2 +- docs/steps-for-ci/index.html | 2 +- docs/support/index.html | 2 +- docs/versions/index.html | 2 +- index.html | 2 +- man/next/infer-analyze.1.html | 854 +++++---- man/next/infer-capture.1.html | 383 ++-- man/next/infer-compile.1.html | 77 +- man/next/infer-debug.1.html | 140 +- man/next/infer-explore.1.html | 54 +- man/next/infer-help.1.html | 62 +- man/next/infer-report.1.html | 208 ++- man/next/infer-reportdiff.1.html | 103 +- man/next/infer-run.1.html | 197 ++- man/next/infer.1.html | 1542 ++++++++--------- .../Absint/AbstractDomain/NodeSet/index.html | 6 + .../module-type-NodeSetS/index.html | 6 + .../Absint/RecursiveCycleException/index.html | 2 + odoc/next/infer/Backend/GCStats/index.html | 2 +- odoc/next/infer/Backend/Ondemand/index.html | 2 +- .../Mem/index.html | 2 + .../Summary/index.html | 2 + .../StaticConstructorStallChecker/index.html | 2 + .../ClangFrontend/CTrans_utils/index.html | 2 +- .../StarvationDomain/ThreadDomain/index.html | 2 +- .../infer/IBase/AnalysisRequest/index.html | 2 +- odoc/next/infer/IBase/Config/index.html | 8 +- .../infer/IBase/EarlyScubaLogging/index.html | 2 - .../infer/IBase/ExecutionDuration/index.html | 2 +- odoc/next/infer/IBase/IssueType/index.html | 2 +- odoc/next/infer/IBase/Language/index.html | 2 +- odoc/next/infer/IBase/LogEntry/index.html | 2 +- odoc/next/infer/IBase/Process/index.html | 8 +- odoc/next/infer/IBase/Scuba/index.html | 2 - odoc/next/infer/IBase/SourceFile/index.html | 2 +- odoc/next/infer/IBase/Stats/index.html | 2 +- .../{ScubaLogging => StatsLogging}/index.html | 4 +- odoc/next/infer/IBase/StatsSample/index.html | 2 + odoc/next/infer/IBase/Timings/index.html | 2 +- odoc/next/infer/IBase/ToplAst/index.html | 2 +- odoc/next/infer/IBase/ToplLexer/index.html | 2 +- odoc/next/infer/IBase/Utils/index.html | 4 +- odoc/next/infer/IBase/index.html | 2 +- .../infer/IR/AnalysisGlobalState/index.html | 7 +- odoc/next/infer/IR/CallFlags/index.html | 2 +- odoc/next/infer/IR/Dependencies/index.html | 2 +- odoc/next/infer/IR/Fieldname/index.html | 2 +- odoc/next/infer/IR/Io_infer/Html/index.html | 11 +- odoc/next/infer/IR/ProcAttributes/index.html | 18 +- odoc/next/infer/IR/Procdesc/Loop/index.html | 2 + .../next/infer/IR/Procdesc/NodeSet/index.html | 2 + odoc/next/infer/IR/Procname/index.html | 4 +- odoc/next/infer/IR/PythonClassName/index.html | 2 +- odoc/next/infer/IR/Typ/Name/index.html | 2 +- odoc/next/infer/IStdlib/IStd/index.html | 2 +- .../next/infer/IStdlib/IString/Map/index.html | 14 + .../next/infer/IStdlib/IString/Set/index.html | 5 + odoc/next/infer/IStdlib/IString/index.html | 2 + .../MakeConcurrentMap/index.html | 2 + .../infer/IStdlib/PrettyPrintable/index.html | 4 +- .../module-type-ConcurrentMap/index.html | 2 + .../CanonValue/Attributes/index.html | 6 +- .../Pulselib/PulseAbductiveDomain/index.html | 13 +- .../Pulselib/PulseAccessResult/index.html | 11 +- .../PulseBaseAddressAttributes/index.html | 6 +- .../module-type-S/index.html | 6 +- .../Pulselib/PulseCallOperations/index.html | 4 +- .../Make/Attributes/index.html | 6 +- .../module-type-S/Attributes/index.html | 6 +- .../infer/Pulselib/PulseDiagnostic/index.html | 4 +- odoc/next/infer/Pulselib/PulseJoin/index.html | 8 + .../Pulselib/PulseModelsDSL/Syntax/index.html | 12 +- .../Pulselib/PulseModelsPython/index.html | 2 + .../Pulselib/PulseMutualRecursion/index.html | 13 +- .../Summary/index.html | 4 +- .../PulseNonDisjunctiveDomain/index.html | 7 +- .../infer/Pulselib/PulseOperations/index.html | 7 +- .../Pulselib/PulsePathContext/index.html | 2 +- .../infer/Pulselib/PulseReport/index.html | 4 + .../infer/Pulselib/PulseResult/index.html | 7 +- .../infer/Pulselib/PulseSummary/index.html | 5 +- .../PulseTaintConfig/SinkPolicy/index.html | 2 +- .../Pulselib/PulseTaintConfig/Unit/index.html | 2 +- .../PythonFrontend/PyIR2Textual/index.html | 4 + .../infer/Textuallib/TextualSil/index.html | 2 +- .../Textuallib/TextualVerification/index.html | 8 + search/index.html | 2 +- 251 files changed, 2196 insertions(+), 2090 deletions(-) rename assets/js/{041e4035.b69a3096.js => 041e4035.e204036c.js} (71%) delete mode 100644 assets/js/223037ba.2aa7902c.js create mode 100644 assets/js/223037ba.890494e4.js rename assets/js/{8fdeae25.904d52c1.js => 8fdeae25.5a49904a.js} (55%) delete mode 100644 assets/js/c359af60.1278ce61.js create mode 100644 assets/js/c359af60.87765c92.js rename assets/js/{runtime~main.bf22b583.js => runtime~main.f2ef44c5.js} (97%) create mode 100644 odoc/next/infer/Absint/AbstractDomain/NodeSet/index.html create mode 100644 odoc/next/infer/Absint/AbstractDomain/module-type-NodeSetS/index.html create mode 100644 odoc/next/infer/Absint/RecursiveCycleException/index.html create mode 100644 odoc/next/infer/Checkers/StaticConstructorStallChecker/Mem/index.html create mode 100644 odoc/next/infer/Checkers/StaticConstructorStallChecker/Summary/index.html create mode 100644 odoc/next/infer/Checkers/StaticConstructorStallChecker/index.html delete mode 100644 odoc/next/infer/IBase/EarlyScubaLogging/index.html delete mode 100644 odoc/next/infer/IBase/Scuba/index.html rename odoc/next/infer/IBase/{ScubaLogging => StatsLogging}/index.html (54%) create mode 100644 odoc/next/infer/IBase/StatsSample/index.html create mode 100644 odoc/next/infer/IR/Procdesc/Loop/index.html create mode 100644 odoc/next/infer/IR/Procdesc/NodeSet/index.html create mode 100644 odoc/next/infer/IStdlib/IString/Map/index.html create mode 100644 odoc/next/infer/IStdlib/IString/Set/index.html create mode 100644 odoc/next/infer/IStdlib/IString/index.html create mode 100644 odoc/next/infer/IStdlib/PrettyPrintable/MakeConcurrentMap/index.html create mode 100644 odoc/next/infer/IStdlib/PrettyPrintable/module-type-ConcurrentMap/index.html create mode 100644 odoc/next/infer/Pulselib/PulseJoin/index.html create mode 100644 odoc/next/infer/Pulselib/PulseModelsPython/index.html create mode 100644 odoc/next/infer/PythonFrontend/PyIR2Textual/index.html create mode 100644 odoc/next/infer/Textuallib/TextualVerification/index.html diff --git a/404.html b/404.html index 55275424a4a..fcf5fdbb1cf 100644 --- a/404.html +++ b/404.html @@ -13,7 +13,7 @@ - + diff --git a/assets/js/041e4035.b69a3096.js b/assets/js/041e4035.e204036c.js similarity index 71% rename from assets/js/041e4035.b69a3096.js rename to assets/js/041e4035.e204036c.js index 57a1bdc155b..f811e060f94 100644 --- a/assets/js/041e4035.b69a3096.js +++ b/assets/js/041e4035.e204036c.js @@ -1 +1 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[8045],{4364:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>c,toc:()=>d});var i=s(4848),t=s(8453);const r={title:"Starvation",description:"Detect various kinds of situations when no progress is being made because of concurrency errors."},o=void 0,c={id:"checker-starvation",title:"Starvation",description:"Detect various kinds of situations when no progress is being made because of concurrency errors.",source:"@site/docs/checker-starvation.md",sourceDirName:".",slug:"/checker-starvation",permalink:"/docs/next/checker-starvation",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"Starvation",description:"Detect various kinds of situations when no progress is being made because of concurrency errors."},sidebar:"docs",previous:{title:"Self in Block",permalink:"/docs/next/checker-self-in-block"},next:{title:"Topl",permalink:"/docs/next/checker-topl"}},l={},d=[{value:"List of Issue Types",id:"list-of-issue-types",level:2}];function a(e){const n={a:"a",code:"code",h2:"h2",li:"li",p:"p",ul:"ul",...(0,t.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.p,{children:"Detect various kinds of situations when no progress is being made because of concurrency errors."}),"\n",(0,i.jsxs)(n.p,{children:["Activate with ",(0,i.jsx)(n.code,{children:"--starvation"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"Supported languages:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"C/C++/ObjC: Yes"}),"\n",(0,i.jsx)(n.li,{children:"C#/.Net: No"}),"\n",(0,i.jsx)(n.li,{children:"Erlang: No"}),"\n",(0,i.jsx)(n.li,{children:"Hack: No"}),"\n",(0,i.jsx)(n.li,{children:"Java: Yes"}),"\n",(0,i.jsx)(n.li,{children:"Python: No"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:'Detect several kinds of "starvation" problems:'}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"deadlocks"}),"\n",(0,i.jsxs)(n.li,{children:["violations of ",(0,i.jsx)(n.code,{children:"@Lockless"})," annotations"]}),"\n",(0,i.jsxs)(n.li,{children:["violations of ",(0,i.jsx)(n.a,{href:"https://developer.android.com/reference/android/os/StrictMode",children:'Android\'s "strict mode"'})]}),"\n",(0,i.jsx)(n.li,{children:"doing expensive operations on the Android UI thread"}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"list-of-issue-types",children:"List of Issue Types"}),"\n",(0,i.jsx)(n.p,{children:"The following issue types are reported by this checker:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"/docs/next/all-issue-types#arbitrary_code_execution_under_lock",children:"ARBITRARY_CODE_EXECUTION_UNDER_LOCK"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"/docs/next/all-issue-types#deadlock",children:"DEADLOCK"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"/docs/next/all-issue-types#ipc_on_ui_thread",children:"IPC_ON_UI_THREAD"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"/docs/next/all-issue-types#lockless_violation",children:"LOCKLESS_VIOLATION"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"/docs/next/all-issue-types#regex_op_on_ui_thread",children:"REGEX_OP_ON_UI_THREAD"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"/docs/next/all-issue-types#starvation",children:"STARVATION"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"/docs/next/all-issue-types#strict_mode_violation",children:"STRICT_MODE_VIOLATION"})}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(a,{...e})}):a(e)}},8453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>c});var i=s(6540);const t={},r=i.createContext(t);function o(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[8045],{4364:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>t,metadata:()=>c,toc:()=>d});var i=s(4848),r=s(8453);const t={title:"Starvation",description:"Detect various kinds of situations when no progress is being made because of concurrency errors."},o=void 0,c={id:"checker-starvation",title:"Starvation",description:"Detect various kinds of situations when no progress is being made because of concurrency errors.",source:"@site/docs/checker-starvation.md",sourceDirName:".",slug:"/checker-starvation",permalink:"/docs/next/checker-starvation",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"Starvation",description:"Detect various kinds of situations when no progress is being made because of concurrency errors."},sidebar:"docs",previous:{title:"Self in Block",permalink:"/docs/next/checker-self-in-block"},next:{title:"Topl",permalink:"/docs/next/checker-topl"}},l={},d=[{value:"List of Issue Types",id:"list-of-issue-types",level:2}];function a(e){const n={a:"a",code:"code",h2:"h2",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.p,{children:"Detect various kinds of situations when no progress is being made because of concurrency errors."}),"\n",(0,i.jsxs)(n.p,{children:["Activate with ",(0,i.jsx)(n.code,{children:"--starvation"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"Supported languages:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"C/C++/ObjC: Yes"}),"\n",(0,i.jsx)(n.li,{children:"C#/.Net: No"}),"\n",(0,i.jsx)(n.li,{children:"Erlang: No"}),"\n",(0,i.jsx)(n.li,{children:"Hack: No"}),"\n",(0,i.jsx)(n.li,{children:"Java: Yes"}),"\n",(0,i.jsx)(n.li,{children:"Python: No"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:'Detect several kinds of "starvation" problems:'}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"deadlocks"}),"\n",(0,i.jsxs)(n.li,{children:["violations of ",(0,i.jsx)(n.code,{children:"@Lockless"})," annotations"]}),"\n",(0,i.jsxs)(n.li,{children:["violations of ",(0,i.jsx)(n.a,{href:"https://developer.android.com/reference/android/os/StrictMode",children:'Android\'s "strict mode"'})]}),"\n",(0,i.jsx)(n.li,{children:"doing expensive operations on the Android UI thread"}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"list-of-issue-types",children:"List of Issue Types"}),"\n",(0,i.jsx)(n.p,{children:"The following issue types are reported by this checker:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"/docs/next/all-issue-types#arbitrary_code_execution_under_lock",children:"ARBITRARY_CODE_EXECUTION_UNDER_LOCK"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"/docs/next/all-issue-types#deadlock",children:"DEADLOCK"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"/docs/next/all-issue-types#ipc_on_ui_thread",children:"IPC_ON_UI_THREAD"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"/docs/next/all-issue-types#lockless_violation",children:"LOCKLESS_VIOLATION"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"/docs/next/all-issue-types#lock_on_ui_thread",children:"LOCK_ON_UI_THREAD"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"/docs/next/all-issue-types#regex_op_on_ui_thread",children:"REGEX_OP_ON_UI_THREAD"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"/docs/next/all-issue-types#starvation",children:"STARVATION"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"/docs/next/all-issue-types#strict_mode_violation",children:"STRICT_MODE_VIOLATION"})}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(a,{...e})}):a(e)}},8453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>c});var i=s(6540);const r={},t=i.createContext(r);function o(e){const n=i.useContext(t);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),i.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/223037ba.2aa7902c.js b/assets/js/223037ba.2aa7902c.js deleted file mode 100644 index c3978ef039c..00000000000 --- a/assets/js/223037ba.2aa7902c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[9383],{1483:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>_,contentTitle:()=>t,default:()=>h,frontMatter:()=>r,metadata:()=>c,toc:()=>a});var l=n(4848),i=n(8453);const r={title:"List of all categories of issue types"},t=void 0,c={id:"all-categories",title:"List of all categories of issue types",description:"Here are all the categories that issue types might belong to in Infer. Some issue types have no associated category at the moment. This usually indicates that the issue type is not yet mature enough to be used.",source:"@site/docs/all-categories.md",sourceDirName:".",slug:"/all-categories",permalink:"/docs/next/all-categories",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"List of all categories of issue types"},sidebar:"docs",previous:{title:"List of all checkers",permalink:"/docs/next/all-checkers"},next:{title:"List of all issue types",permalink:"/docs/next/all-issue-types"}},_={},a=[{value:"Concurrency",id:"concurrency",level:2},{value:"Logic error",id:"logic-error",level:2},{value:"Memory error",id:"memory-error",level:2},{value:"Null pointer dereference",id:"null-pointer-dereference",level:2},{value:"Perf regression",id:"perf-regression",level:2},{value:"Resource leak",id:"resource-leak",level:2},{value:"Runtime exception",id:"runtime-exception",level:2},{value:"Sensitive data flow",id:"sensitive-data-flow",level:2},{value:"Ungated code",id:"ungated-code",level:2},{value:"User defined property",id:"user-defined-property",level:2}];function d(e){const s={a:"a",h2:"h2",li:"li",p:"p",ul:"ul",...(0,i.R)(),...e.components};return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(s.p,{children:"Here are all the categories that issue types might belong to in Infer. Some issue types have no associated category at the moment. This usually indicates that the issue type is not yet mature enough to be used."}),"\n",(0,l.jsx)(s.h2,{id:"concurrency",children:"Concurrency"}),"\n",(0,l.jsx)(s.p,{children:"Concurrent accesses to the same resource conflict in a way that can give incorrect results, block progress, or result in undefined behaviour."}),"\n",(0,l.jsx)(s.p,{children:"Issue types in this category:"}),"\n",(0,l.jsxs)(s.ul,{children:["\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#deadlock",children:"DEADLOCK"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#guardedby_violation",children:"GUARDEDBY_VIOLATION"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#interface_not_thread_safe",children:"INTERFACE_NOT_THREAD_SAFE"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#lock_consistency_violation",children:"LOCK_CONSISTENCY_VIOLATION"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#static_constructor_stall",children:"STATIC_CONSTRUCTOR_STALL"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#thread_safety_violation",children:"THREAD_SAFETY_VIOLATION"})}),"\n"]}),"\n",(0,l.jsx)(s.h2,{id:"logic-error",children:"Logic error"}),"\n",(0,l.jsx)(s.p,{children:"Something that does not make sense and the sign of a potential programming error."}),"\n",(0,l.jsx)(s.p,{children:"Issue types in this category:"}),"\n",(0,l.jsxs)(s.ul,{children:["\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#dead_store",children:"DEAD_STORE"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#pulse_transitive_access",children:"PULSE_TRANSITIVE_ACCESS"})}),"\n"]}),"\n",(0,l.jsx)(s.h2,{id:"memory-error",children:"Memory error"}),"\n",(0,l.jsx)(s.p,{children:"Incorrect handling of pointers that isn't a null pointer dereference, but can still result in undefined behaviour and crashes."}),"\n",(0,l.jsx)(s.p,{children:"Issue types in this category:"}),"\n",(0,l.jsxs)(s.ul,{children:["\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#cxx_ref_captured_in_block",children:"CXX_REF_CAPTURED_IN_BLOCK"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#cxx_string_captured_in_block",children:"CXX_STRING_CAPTURED_IN_BLOCK"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#nil_messaging_to_non_pod",children:"NIL_MESSAGING_TO_NON_POD"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#nil_messaging_to_non_pod_latent",children:"NIL_MESSAGING_TO_NON_POD_LATENT"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#nsstring_internal_ptr_captured_in_block",children:"NSSTRING_INTERNAL_PTR_CAPTURED_IN_BLOCK"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#pulse_reference_stability",children:"PULSE_REFERENCE_STABILITY"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#pulse_uninitialized_value",children:"PULSE_UNINITIALIZED_VALUE"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#stack_variable_address_escape",children:"STACK_VARIABLE_ADDRESS_ESCAPE"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#static_initialization_order_fiasco",children:"STATIC_INITIALIZATION_ORDER_FIASCO"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#strong_self_not_checked",children:"STRONG_SELF_NOT_CHECKED"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#use_after_delete",children:"USE_AFTER_DELETE"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#use_after_delete_latent",children:"USE_AFTER_DELETE_LATENT"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#use_after_free",children:"USE_AFTER_FREE"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#use_after_free_latent",children:"USE_AFTER_FREE_LATENT"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#use_after_lifetime",children:"USE_AFTER_LIFETIME"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#use_after_lifetime_latent",children:"USE_AFTER_LIFETIME_LATENT"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#vector_invalidation",children:"VECTOR_INVALIDATION"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#vector_invalidation_latent",children:"VECTOR_INVALIDATION_LATENT"})}),"\n"]}),"\n",(0,l.jsx)(s.h2,{id:"null-pointer-dereference",children:"Null pointer dereference"}),"\n",(0,l.jsx)(s.p,{children:"The null pointer is used where a valid pointer is required, causing a memory fault and a crash. For example, it is dereferenced."}),"\n",(0,l.jsx)(s.p,{children:"Issue types in this category:"}),"\n",(0,l.jsxs)(s.ul,{children:["\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#block_parameter_not_null_checked",children:"BLOCK_PARAMETER_NOT_NULL_CHECKED"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#compared_to_null_and_dereferenced",children:"COMPARED_TO_NULL_AND_DEREFERENCED"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#nil_block_call",children:"NIL_BLOCK_CALL"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#nil_block_call_latent",children:"NIL_BLOCK_CALL_LATENT"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#nullptr_dereference",children:"NULLPTR_DEREFERENCE"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#nullptr_dereference_in_nullsafe_class",children:"NULLPTR_DEREFERENCE_IN_NULLSAFE_CLASS"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#nullptr_dereference_in_nullsafe_class_latent",children:"NULLPTR_DEREFERENCE_IN_NULLSAFE_CLASS_LATENT"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#nullptr_dereference_latent",children:"NULLPTR_DEREFERENCE_LATENT"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#null_dereference",children:"NULL_DEREFERENCE"})}),"\n"]}),"\n",(0,l.jsx)(s.h2,{id:"perf-regression",children:"Perf regression"}),"\n",(0,l.jsx)(s.p,{children:"Unnecessary (or blocking) computation is performed, potentially causing a performance or responsiveness regression."}),"\n",(0,l.jsx)(s.p,{children:"Issue types in this category:"}),"\n",(0,l.jsxs)(s.ul,{children:["\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#checkers_allocates_memory",children:"CHECKERS_ALLOCATES_MEMORY"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#checkers_calls_expensive_method",children:"CHECKERS_CALLS_EXPENSIVE_METHOD"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#config_impact",children:"CONFIG_IMPACT"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#inefficient_keyset_iterator",children:"INEFFICIENT_KEYSET_ITERATOR"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#ipc_on_ui_thread",children:"IPC_ON_UI_THREAD"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#pulse_const_refable",children:"PULSE_CONST_REFABLE"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#pulse_readonly_shared_ptr_param",children:"PULSE_READONLY_SHARED_PTR_PARAM"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#pulse_unnecessary_copy",children:"PULSE_UNNECESSARY_COPY"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#pulse_unnecessary_copy_assignment",children:"PULSE_UNNECESSARY_COPY_ASSIGNMENT"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#pulse_unnecessary_copy_assignment_const",children:"PULSE_UNNECESSARY_COPY_ASSIGNMENT_CONST"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#pulse_unnecessary_copy_assignment_movable",children:"PULSE_UNNECESSARY_COPY_ASSIGNMENT_MOVABLE"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#pulse_unnecessary_copy_intermediate",children:"PULSE_UNNECESSARY_COPY_INTERMEDIATE"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#pulse_unnecessary_copy_intermediate_const",children:"PULSE_UNNECESSARY_COPY_INTERMEDIATE_CONST"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#pulse_unnecessary_copy_movable",children:"PULSE_UNNECESSARY_COPY_MOVABLE"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#pulse_unnecessary_copy_optional",children:"PULSE_UNNECESSARY_COPY_OPTIONAL"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#pulse_unnecessary_copy_optional_const",children:"PULSE_UNNECESSARY_COPY_OPTIONAL_CONST"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#pulse_unnecessary_copy_return",children:"PULSE_UNNECESSARY_COPY_RETURN"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#pulse_unnecessary_copy_thrift_assignment",children:"PULSE_UNNECESSARY_COPY_THRIFT_ASSIGNMENT"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#regex_op_on_ui_thread",children:"REGEX_OP_ON_UI_THREAD"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#strict_mode_violation",children:"STRICT_MODE_VIOLATION"})}),"\n"]}),"\n",(0,l.jsx)(s.h2,{id:"resource-leak",children:"Resource leak"}),"\n",(0,l.jsx)(s.p,{children:"A resource (for example memory, or a file descriptor) has been manually allocated but not released, possibly creating memory pressure over time or even incorrect results."}),"\n",(0,l.jsx)(s.p,{children:"Issue types in this category:"}),"\n",(0,l.jsxs)(s.ul,{children:["\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#biabduction_memory_leak",children:"BIABDUCTION_MEMORY_LEAK"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#biabduction_retain_cycle",children:"BIABDUCTION_RETAIN_CYCLE"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#captured_strong_self",children:"CAPTURED_STRONG_SELF"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#checkers_fragment_retains_view",children:"CHECKERS_FRAGMENT_RETAINS_VIEW"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#memory_leak_c",children:"MEMORY_LEAK_C"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#memory_leak_cpp",children:"MEMORY_LEAK_CPP"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#mixed_self_weakself",children:"MIXED_SELF_WEAKSELF"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#pulse_resource_leak",children:"PULSE_RESOURCE_LEAK"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#pulse_unawaited_awaitable",children:"PULSE_UNAWAITED_AWAITABLE"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#pulse_unfinished_builder",children:"PULSE_UNFINISHED_BUILDER"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#resource_leak",children:"RESOURCE_LEAK"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#retain_cycle",children:"RETAIN_CYCLE"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#retain_cycle_no_weak_info",children:"RETAIN_CYCLE_NO_WEAK_INFO"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#self_in_block_passed_to_init",children:"SELF_IN_BLOCK_PASSED_TO_INIT"})}),"\n"]}),"\n",(0,l.jsx)(s.h2,{id:"runtime-exception",children:"Runtime exception"}),"\n",(0,l.jsx)(s.p,{children:"A runtime exception can occur and potentially crash the program."}),"\n",(0,l.jsx)(s.p,{children:"Issue types in this category:"}),"\n",(0,l.jsxs)(s.ul,{children:["\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#bad_arg",children:"BAD_ARG"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#bad_arg_latent",children:"BAD_ARG_LATENT"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#bad_generator",children:"BAD_GENERATOR"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#bad_generator_latent",children:"BAD_GENERATOR_LATENT"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#bad_key",children:"BAD_KEY"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#bad_key_latent",children:"BAD_KEY_LATENT"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#bad_map",children:"BAD_MAP"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#bad_map_latent",children:"BAD_MAP_LATENT"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#bad_record",children:"BAD_RECORD"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#bad_record_latent",children:"BAD_RECORD_LATENT"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#missing_required_prop",children:"MISSING_REQUIRED_PROP"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#mutual_recursion_cycle",children:"MUTUAL_RECURSION_CYCLE"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#nil_insertion_into_collection",children:"NIL_INSERTION_INTO_COLLECTION"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#nil_insertion_into_collection_latent",children:"NIL_INSERTION_INTO_COLLECTION_LATENT"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#no_matching_branch_in_try",children:"NO_MATCHING_BRANCH_IN_TRY"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#no_matching_branch_in_try_latent",children:"NO_MATCHING_BRANCH_IN_TRY_LATENT"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#no_matching_case_clause",children:"NO_MATCHING_CASE_CLAUSE"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#no_matching_case_clause_latent",children:"NO_MATCHING_CASE_CLAUSE_LATENT"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#no_matching_else_clause",children:"NO_MATCHING_ELSE_CLAUSE"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#no_matching_else_clause_latent",children:"NO_MATCHING_ELSE_CLAUSE_LATENT"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#no_matching_function_clause",children:"NO_MATCHING_FUNCTION_CLAUSE"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#no_matching_function_clause_latent",children:"NO_MATCHING_FUNCTION_CLAUSE_LATENT"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#no_match_of_rhs",children:"NO_MATCH_OF_RHS"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#no_match_of_rhs_latent",children:"NO_MATCH_OF_RHS_LATENT"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#no_true_branch_in_if",children:"NO_TRUE_BRANCH_IN_IF"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#no_true_branch_in_if_latent",children:"NO_TRUE_BRANCH_IN_IF_LATENT"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#null_argument",children:"NULL_ARGUMENT"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#null_argument_latent",children:"NULL_ARGUMENT_LATENT"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#optional_empty_access",children:"OPTIONAL_EMPTY_ACCESS"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#optional_empty_access_latent",children:"OPTIONAL_EMPTY_ACCESS_LATENT"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#pulse_cannot_instantiate_abstract_class",children:"PULSE_CANNOT_INSTANTIATE_ABSTRACT_CLASS"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#pulse_dict_missing_key",children:"PULSE_DICT_MISSING_KEY"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#pulse_dynamic_type_mismatch",children:"PULSE_DYNAMIC_TYPE_MISMATCH"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#pulse_uninitialized_const",children:"PULSE_UNINITIALIZED_CONST"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#pulse_uninitialized_method",children:"PULSE_UNINITIALIZED_METHOD"})}),"\n"]}),"\n",(0,l.jsx)(s.h2,{id:"sensitive-data-flow",children:"Sensitive data flow"}),"\n",(0,l.jsx)(s.p,{children:"Sensitive data is flowing where it shouldn't."}),"\n",(0,l.jsx)(s.p,{children:"Issue types in this category:"}),"\n",(0,l.jsxs)(s.ul,{children:["\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#data_flow_to_sink",children:"DATA_FLOW_TO_SINK"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#lineage_flow",children:"LINEAGE_FLOW"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#scope_leakage",children:"SCOPE_LEAKAGE"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#sensitive_data_flow",children:"SENSITIVE_DATA_FLOW"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#taint_error",children:"TAINT_ERROR"})}),"\n"]}),"\n",(0,l.jsx)(s.h2,{id:"ungated-code",children:"Ungated code"}),"\n",(0,l.jsx)(s.p,{children:"Code must be under a gating mechanism but isn't."}),"\n",(0,l.jsx)(s.p,{children:"Issue types in this category:"}),"\n",(0,l.jsxs)(s.ul,{children:["\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#config_impact_strict",children:"CONFIG_IMPACT_STRICT"})}),"\n"]}),"\n",(0,l.jsx)(s.h2,{id:"user-defined-property",children:"User defined property"}),"\n",(0,l.jsx)(s.p,{children:"A user defined (custom) property is violated."}),"\n",(0,l.jsx)(s.p,{children:"Issue types in this category:"}),"\n",(0,l.jsxs)(s.ul,{children:["\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#checkers_annotation_reachability_error",children:"CHECKERS_ANNOTATION_REACHABILITY_ERROR"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#topl_error",children:"TOPL_ERROR"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#topl_error_latent",children:"TOPL_ERROR_LATENT"})}),"\n"]})]})}function h(e={}){const{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,l.jsx)(s,{...e,children:(0,l.jsx)(d,{...e})}):d(e)}},8453:(e,s,n)=>{n.d(s,{R:()=>t,x:()=>c});var l=n(6540);const i={},r=l.createContext(i);function t(e){const s=l.useContext(r);return l.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function c(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:t(e.components),l.createElement(r.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/223037ba.890494e4.js b/assets/js/223037ba.890494e4.js new file mode 100644 index 00000000000..30f3a1d1b09 --- /dev/null +++ b/assets/js/223037ba.890494e4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[9383],{1483:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>_,contentTitle:()=>t,default:()=>h,frontMatter:()=>r,metadata:()=>c,toc:()=>a});var l=n(4848),i=n(8453);const r={title:"List of all categories of issue types"},t=void 0,c={id:"all-categories",title:"List of all categories of issue types",description:"Here are all the categories that issue types might belong to in Infer. Some issue types have no associated category at the moment. This usually indicates that the issue type is not yet mature enough to be used.",source:"@site/docs/all-categories.md",sourceDirName:".",slug:"/all-categories",permalink:"/docs/next/all-categories",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"List of all categories of issue types"},sidebar:"docs",previous:{title:"List of all checkers",permalink:"/docs/next/all-checkers"},next:{title:"List of all issue types",permalink:"/docs/next/all-issue-types"}},_={},a=[{value:"Concurrency",id:"concurrency",level:2},{value:"Logic error",id:"logic-error",level:2},{value:"Memory error",id:"memory-error",level:2},{value:"Null pointer dereference",id:"null-pointer-dereference",level:2},{value:"Perf regression",id:"perf-regression",level:2},{value:"Resource leak",id:"resource-leak",level:2},{value:"Runtime exception",id:"runtime-exception",level:2},{value:"Sensitive data flow",id:"sensitive-data-flow",level:2},{value:"Ungated code",id:"ungated-code",level:2},{value:"User defined property",id:"user-defined-property",level:2}];function d(e){const s={a:"a",h2:"h2",li:"li",p:"p",ul:"ul",...(0,i.R)(),...e.components};return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(s.p,{children:"Here are all the categories that issue types might belong to in Infer. Some issue types have no associated category at the moment. This usually indicates that the issue type is not yet mature enough to be used."}),"\n",(0,l.jsx)(s.h2,{id:"concurrency",children:"Concurrency"}),"\n",(0,l.jsx)(s.p,{children:"Concurrent accesses to the same resource conflict in a way that can give incorrect results, block progress, or result in undefined behaviour."}),"\n",(0,l.jsx)(s.p,{children:"Issue types in this category:"}),"\n",(0,l.jsxs)(s.ul,{children:["\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#deadlock",children:"DEADLOCK"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#guardedby_violation",children:"GUARDEDBY_VIOLATION"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#interface_not_thread_safe",children:"INTERFACE_NOT_THREAD_SAFE"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#lock_consistency_violation",children:"LOCK_CONSISTENCY_VIOLATION"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#static_constructor_stall",children:"STATIC_CONSTRUCTOR_STALL"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#thread_safety_violation",children:"THREAD_SAFETY_VIOLATION"})}),"\n"]}),"\n",(0,l.jsx)(s.h2,{id:"logic-error",children:"Logic error"}),"\n",(0,l.jsx)(s.p,{children:"Something that does not make sense and the sign of a potential programming error."}),"\n",(0,l.jsx)(s.p,{children:"Issue types in this category:"}),"\n",(0,l.jsxs)(s.ul,{children:["\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#dead_store",children:"DEAD_STORE"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#pulse_transitive_access",children:"PULSE_TRANSITIVE_ACCESS"})}),"\n"]}),"\n",(0,l.jsx)(s.h2,{id:"memory-error",children:"Memory error"}),"\n",(0,l.jsx)(s.p,{children:"Incorrect handling of pointers that isn't a null pointer dereference, but can still result in undefined behaviour and crashes."}),"\n",(0,l.jsx)(s.p,{children:"Issue types in this category:"}),"\n",(0,l.jsxs)(s.ul,{children:["\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#cxx_ref_captured_in_block",children:"CXX_REF_CAPTURED_IN_BLOCK"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#cxx_string_captured_in_block",children:"CXX_STRING_CAPTURED_IN_BLOCK"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#nil_messaging_to_non_pod",children:"NIL_MESSAGING_TO_NON_POD"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#nil_messaging_to_non_pod_latent",children:"NIL_MESSAGING_TO_NON_POD_LATENT"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#nsstring_internal_ptr_captured_in_block",children:"NSSTRING_INTERNAL_PTR_CAPTURED_IN_BLOCK"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#pulse_reference_stability",children:"PULSE_REFERENCE_STABILITY"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#pulse_uninitialized_value",children:"PULSE_UNINITIALIZED_VALUE"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#stack_variable_address_escape",children:"STACK_VARIABLE_ADDRESS_ESCAPE"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#static_initialization_order_fiasco",children:"STATIC_INITIALIZATION_ORDER_FIASCO"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#strong_self_not_checked",children:"STRONG_SELF_NOT_CHECKED"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#use_after_delete",children:"USE_AFTER_DELETE"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#use_after_delete_latent",children:"USE_AFTER_DELETE_LATENT"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#use_after_free",children:"USE_AFTER_FREE"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#use_after_free_latent",children:"USE_AFTER_FREE_LATENT"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#use_after_lifetime",children:"USE_AFTER_LIFETIME"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#use_after_lifetime_latent",children:"USE_AFTER_LIFETIME_LATENT"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#vector_invalidation",children:"VECTOR_INVALIDATION"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#vector_invalidation_latent",children:"VECTOR_INVALIDATION_LATENT"})}),"\n"]}),"\n",(0,l.jsx)(s.h2,{id:"null-pointer-dereference",children:"Null pointer dereference"}),"\n",(0,l.jsx)(s.p,{children:"The null pointer is used where a valid pointer is required, causing a memory fault and a crash. For example, it is dereferenced."}),"\n",(0,l.jsx)(s.p,{children:"Issue types in this category:"}),"\n",(0,l.jsxs)(s.ul,{children:["\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#block_parameter_not_null_checked",children:"BLOCK_PARAMETER_NOT_NULL_CHECKED"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#compared_to_null_and_dereferenced",children:"COMPARED_TO_NULL_AND_DEREFERENCED"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#nil_block_call",children:"NIL_BLOCK_CALL"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#nil_block_call_latent",children:"NIL_BLOCK_CALL_LATENT"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#nullptr_dereference",children:"NULLPTR_DEREFERENCE"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#nullptr_dereference_in_nullsafe_class",children:"NULLPTR_DEREFERENCE_IN_NULLSAFE_CLASS"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#nullptr_dereference_in_nullsafe_class_latent",children:"NULLPTR_DEREFERENCE_IN_NULLSAFE_CLASS_LATENT"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#nullptr_dereference_latent",children:"NULLPTR_DEREFERENCE_LATENT"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#null_dereference",children:"NULL_DEREFERENCE"})}),"\n"]}),"\n",(0,l.jsx)(s.h2,{id:"perf-regression",children:"Perf regression"}),"\n",(0,l.jsx)(s.p,{children:"Unnecessary (or blocking) computation is performed, potentially causing a performance or responsiveness regression."}),"\n",(0,l.jsx)(s.p,{children:"Issue types in this category:"}),"\n",(0,l.jsxs)(s.ul,{children:["\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#checkers_allocates_memory",children:"CHECKERS_ALLOCATES_MEMORY"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#checkers_calls_expensive_method",children:"CHECKERS_CALLS_EXPENSIVE_METHOD"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#config_impact",children:"CONFIG_IMPACT"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#inefficient_keyset_iterator",children:"INEFFICIENT_KEYSET_ITERATOR"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#ipc_on_ui_thread",children:"IPC_ON_UI_THREAD"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#lock_on_ui_thread",children:"LOCK_ON_UI_THREAD"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#pulse_const_refable",children:"PULSE_CONST_REFABLE"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#pulse_readonly_shared_ptr_param",children:"PULSE_READONLY_SHARED_PTR_PARAM"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#pulse_unnecessary_copy",children:"PULSE_UNNECESSARY_COPY"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#pulse_unnecessary_copy_assignment",children:"PULSE_UNNECESSARY_COPY_ASSIGNMENT"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#pulse_unnecessary_copy_assignment_const",children:"PULSE_UNNECESSARY_COPY_ASSIGNMENT_CONST"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#pulse_unnecessary_copy_assignment_movable",children:"PULSE_UNNECESSARY_COPY_ASSIGNMENT_MOVABLE"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#pulse_unnecessary_copy_intermediate",children:"PULSE_UNNECESSARY_COPY_INTERMEDIATE"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#pulse_unnecessary_copy_intermediate_const",children:"PULSE_UNNECESSARY_COPY_INTERMEDIATE_CONST"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#pulse_unnecessary_copy_movable",children:"PULSE_UNNECESSARY_COPY_MOVABLE"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#pulse_unnecessary_copy_optional",children:"PULSE_UNNECESSARY_COPY_OPTIONAL"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#pulse_unnecessary_copy_optional_const",children:"PULSE_UNNECESSARY_COPY_OPTIONAL_CONST"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#pulse_unnecessary_copy_return",children:"PULSE_UNNECESSARY_COPY_RETURN"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#pulse_unnecessary_copy_thrift_assignment",children:"PULSE_UNNECESSARY_COPY_THRIFT_ASSIGNMENT"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#regex_op_on_ui_thread",children:"REGEX_OP_ON_UI_THREAD"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#strict_mode_violation",children:"STRICT_MODE_VIOLATION"})}),"\n"]}),"\n",(0,l.jsx)(s.h2,{id:"resource-leak",children:"Resource leak"}),"\n",(0,l.jsx)(s.p,{children:"A resource (for example memory, or a file descriptor) has been manually allocated but not released, possibly creating memory pressure over time or even incorrect results."}),"\n",(0,l.jsx)(s.p,{children:"Issue types in this category:"}),"\n",(0,l.jsxs)(s.ul,{children:["\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#biabduction_memory_leak",children:"BIABDUCTION_MEMORY_LEAK"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#biabduction_retain_cycle",children:"BIABDUCTION_RETAIN_CYCLE"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#captured_strong_self",children:"CAPTURED_STRONG_SELF"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#checkers_fragment_retains_view",children:"CHECKERS_FRAGMENT_RETAINS_VIEW"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#memory_leak_c",children:"MEMORY_LEAK_C"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#memory_leak_cpp",children:"MEMORY_LEAK_CPP"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#mixed_self_weakself",children:"MIXED_SELF_WEAKSELF"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#pulse_resource_leak",children:"PULSE_RESOURCE_LEAK"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#pulse_unawaited_awaitable",children:"PULSE_UNAWAITED_AWAITABLE"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#pulse_unfinished_builder",children:"PULSE_UNFINISHED_BUILDER"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#resource_leak",children:"RESOURCE_LEAK"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#retain_cycle",children:"RETAIN_CYCLE"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#retain_cycle_no_weak_info",children:"RETAIN_CYCLE_NO_WEAK_INFO"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#self_in_block_passed_to_init",children:"SELF_IN_BLOCK_PASSED_TO_INIT"})}),"\n"]}),"\n",(0,l.jsx)(s.h2,{id:"runtime-exception",children:"Runtime exception"}),"\n",(0,l.jsx)(s.p,{children:"A runtime exception can occur and potentially crash the program."}),"\n",(0,l.jsx)(s.p,{children:"Issue types in this category:"}),"\n",(0,l.jsxs)(s.ul,{children:["\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#bad_arg",children:"BAD_ARG"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#bad_arg_latent",children:"BAD_ARG_LATENT"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#bad_generator",children:"BAD_GENERATOR"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#bad_generator_latent",children:"BAD_GENERATOR_LATENT"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#bad_key",children:"BAD_KEY"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#bad_key_latent",children:"BAD_KEY_LATENT"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#bad_map",children:"BAD_MAP"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#bad_map_latent",children:"BAD_MAP_LATENT"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#bad_record",children:"BAD_RECORD"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#bad_record_latent",children:"BAD_RECORD_LATENT"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#infinite_recursion",children:"INFINITE_RECURSION"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#missing_required_prop",children:"MISSING_REQUIRED_PROP"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#mutual_recursion_cycle",children:"MUTUAL_RECURSION_CYCLE"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#nil_insertion_into_collection",children:"NIL_INSERTION_INTO_COLLECTION"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#nil_insertion_into_collection_latent",children:"NIL_INSERTION_INTO_COLLECTION_LATENT"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#no_matching_branch_in_try",children:"NO_MATCHING_BRANCH_IN_TRY"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#no_matching_branch_in_try_latent",children:"NO_MATCHING_BRANCH_IN_TRY_LATENT"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#no_matching_case_clause",children:"NO_MATCHING_CASE_CLAUSE"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#no_matching_case_clause_latent",children:"NO_MATCHING_CASE_CLAUSE_LATENT"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#no_matching_else_clause",children:"NO_MATCHING_ELSE_CLAUSE"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#no_matching_else_clause_latent",children:"NO_MATCHING_ELSE_CLAUSE_LATENT"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#no_matching_function_clause",children:"NO_MATCHING_FUNCTION_CLAUSE"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#no_matching_function_clause_latent",children:"NO_MATCHING_FUNCTION_CLAUSE_LATENT"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#no_match_of_rhs",children:"NO_MATCH_OF_RHS"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#no_match_of_rhs_latent",children:"NO_MATCH_OF_RHS_LATENT"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#no_true_branch_in_if",children:"NO_TRUE_BRANCH_IN_IF"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#no_true_branch_in_if_latent",children:"NO_TRUE_BRANCH_IN_IF_LATENT"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#null_argument",children:"NULL_ARGUMENT"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#null_argument_latent",children:"NULL_ARGUMENT_LATENT"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#optional_empty_access",children:"OPTIONAL_EMPTY_ACCESS"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#optional_empty_access_latent",children:"OPTIONAL_EMPTY_ACCESS_LATENT"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#pulse_cannot_instantiate_abstract_class",children:"PULSE_CANNOT_INSTANTIATE_ABSTRACT_CLASS"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#pulse_dict_missing_key",children:"PULSE_DICT_MISSING_KEY"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#pulse_dynamic_type_mismatch",children:"PULSE_DYNAMIC_TYPE_MISMATCH"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#pulse_uninitialized_const",children:"PULSE_UNINITIALIZED_CONST"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#pulse_uninitialized_method",children:"PULSE_UNINITIALIZED_METHOD"})}),"\n"]}),"\n",(0,l.jsx)(s.h2,{id:"sensitive-data-flow",children:"Sensitive data flow"}),"\n",(0,l.jsx)(s.p,{children:"Sensitive data is flowing where it shouldn't."}),"\n",(0,l.jsx)(s.p,{children:"Issue types in this category:"}),"\n",(0,l.jsxs)(s.ul,{children:["\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#data_flow_to_sink",children:"DATA_FLOW_TO_SINK"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#lineage_flow",children:"LINEAGE_FLOW"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#scope_leakage",children:"SCOPE_LEAKAGE"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#sensitive_data_flow",children:"SENSITIVE_DATA_FLOW"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#taint_error",children:"TAINT_ERROR"})}),"\n"]}),"\n",(0,l.jsx)(s.h2,{id:"ungated-code",children:"Ungated code"}),"\n",(0,l.jsx)(s.p,{children:"Code must be under a gating mechanism but isn't."}),"\n",(0,l.jsx)(s.p,{children:"Issue types in this category:"}),"\n",(0,l.jsxs)(s.ul,{children:["\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#config_impact_strict",children:"CONFIG_IMPACT_STRICT"})}),"\n"]}),"\n",(0,l.jsx)(s.h2,{id:"user-defined-property",children:"User defined property"}),"\n",(0,l.jsx)(s.p,{children:"A user defined (custom) property is violated."}),"\n",(0,l.jsx)(s.p,{children:"Issue types in this category:"}),"\n",(0,l.jsxs)(s.ul,{children:["\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#checkers_annotation_reachability_error",children:"CHECKERS_ANNOTATION_REACHABILITY_ERROR"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#topl_error",children:"TOPL_ERROR"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"/docs/next/all-issue-types#topl_error_latent",children:"TOPL_ERROR_LATENT"})}),"\n"]})]})}function h(e={}){const{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,l.jsx)(s,{...e,children:(0,l.jsx)(d,{...e})}):d(e)}},8453:(e,s,n)=>{n.d(s,{R:()=>t,x:()=>c});var l=n(6540);const i={},r=l.createContext(i);function t(e){const s=l.useContext(r);return l.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function c(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:t(e.components),l.createElement(r.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/8fdeae25.904d52c1.js b/assets/js/8fdeae25.5a49904a.js similarity index 55% rename from assets/js/8fdeae25.904d52c1.js rename to assets/js/8fdeae25.5a49904a.js index 67893e0777b..fb91e920453 100644 --- a/assets/js/8fdeae25.904d52c1.js +++ b/assets/js/8fdeae25.5a49904a.js @@ -1 +1 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[9437],{930:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>t,default:()=>h,frontMatter:()=>r,metadata:()=>c,toc:()=>d});var l=s(4848),i=s(8453);const r={title:"Pulse",description:"General-purpose memory and value analysis engine."},t=void 0,c={id:"checker-pulse",title:"Pulse",description:"General-purpose memory and value analysis engine.",source:"@site/docs/checker-pulse.md",sourceDirName:".",slug:"/checker-pulse",permalink:"/docs/next/checker-pulse",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"Pulse",description:"General-purpose memory and value analysis engine."},sidebar:"docs",previous:{title:"Parameter Not Null Checked",permalink:"/docs/next/checker-parameter-not-null-checked"},next:{title:"Purity",permalink:"/docs/next/checker-purity"}},a={},d=[{value:"What is Infer?",id:"what-is-infer",level:2},{value:"Latent Issues",id:"latent-issues",level:2},{value:"Unknown Functions",id:"unknown-functions",level:2},{value:"Pulse x Nullsafe",id:"pulse-x-nullsafe",level:2},{value:"List of Issue Types",id:"list-of-issue-types",level:2}];function o(e){const n={a:"a",code:"code",em:"em",h2:"h2",li:"li",p:"p",pre:"pre",ul:"ul",...(0,i.R)(),...e.components};return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(n.p,{children:"General-purpose memory and value analysis engine."}),"\n",(0,l.jsxs)(n.p,{children:["Activate with ",(0,l.jsx)(n.code,{children:"--pulse"}),"."]}),"\n",(0,l.jsx)(n.p,{children:"Supported languages:"}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:"C/C++/ObjC: Yes"}),"\n",(0,l.jsx)(n.li,{children:"C#/.Net: No"}),"\n",(0,l.jsx)(n.li,{children:"Erlang: Experimental"}),"\n",(0,l.jsx)(n.li,{children:"Hack: Yes"}),"\n",(0,l.jsx)(n.li,{children:"Java: Yes"}),"\n",(0,l.jsx)(n.li,{children:"Python: No"}),"\n"]}),"\n",(0,l.jsxs)(n.h2,{id:"what-is-infer",children:["What is Infer",":Pulse","?"]}),"\n",(0,l.jsxs)(n.p,{children:["Pulse is an interprocedural memory safety analysis. Pulse can detect, for instance, ",(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#nullptr_dereference",children:"Null dereferences"})," in Java. Errors are only reported when all conditions on the erroneous path are true regardless of input. Pulse should gradually replace the original ",(0,l.jsx)(n.a,{href:"/docs/next/checker-biabduction",children:"biabduction"})," analysis of Infer. An example of a Null dereference found by Pulse is given below."]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-java",children:"class Person {\n Person emergencyContact;\n String address;\n\n Person getEmergencyContact() {\n return this.emergencyContact;\n }\n}\n\nclass Registry {\n void create() {\n Person p = new Person();\n Person c = p.getEmergencyContact();\n // Null dereference here\n System.out.println(c.address);\n }\n\n void printContact(Person p) {\n // No null dereference, as we don't know anything about `p`\n System.out.println(p.getEmergencyContact().address);\n }\n}\n"})}),"\n",(0,l.jsx)(n.p,{children:"How to run pulse for Java:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"infer run --pulse -- javac Test.java\n"})}),"\n",(0,l.jsxs)(n.p,{children:["Pulse reports a Null dereference on this file on ",(0,l.jsx)(n.code,{children:"create()"}),", as it tries to access the field ",(0,l.jsx)(n.code,{children:"address"})," of object ",(0,l.jsx)(n.code,{children:"c"}),", and ",(0,l.jsx)(n.code,{children:"c"})," has value ",(0,l.jsx)(n.code,{children:"null"}),". In contrast, Pulse gives no report for ",(0,l.jsx)(n.code,{children:"printContact(Person p)"}),", as we cannot be sure that ",(0,l.jsx)(n.code,{children:"p.getEmergencyContact()"})," will return ",(0,l.jsx)(n.code,{children:"null"}),". But, thanks to the fact that the analysis is ",(0,l.jsx)(n.em,{children:"inter-procedural"}),", Pulse will report a Null dereference on calls to ",(0,l.jsx)(n.code,{children:"printContact(p)"})," when it detects that ",(0,l.jsx)(n.code,{children:"p"})," is null."]}),"\n",(0,l.jsx)(n.h2,{id:"latent-issues",children:"Latent Issues"}),"\n",(0,l.jsxs)(n.p,{children:["When an error can occur only on some values of the parameters of the current function, Pulse does not report an issue. Such issues are called ",(0,l.jsx)(n.em,{children:"latent"}),". But, if Pulse then sees a call site at which all the conditions for the error are satisfied then the error becomes ",(0,l.jsx)(n.em,{children:"manifest"})," and is reported. This example (in C) illustrates how latent issues are created and then reported when they become manifest:"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-c",children:"// for more realism, imagine that this function does other things as well\nvoid set_to_null_if_positive(int n, int* p) {\n if (n > 0) {\n p = NULL;\n }\n}\n\nvoid latent_null_dereference(int n, int* p) {\n set_to_null_if_positive(n, p);\n *p = 42; // NULL dereference! but only if n > 0 so no report yet\n}\n\nvoid manifest_error(int *p) {\n // no way to avoid the bug here => Pulse reports an error\n latent_null_dereference(1, p);\n}\n"})}),"\n",(0,l.jsx)(n.h2,{id:"unknown-functions",children:"Unknown Functions"}),"\n",(0,l.jsx)(n.p,{children:"In order to avoid false positives, Pulse makes optimistic assumptions about calls to unknown functions. Unknown functions (or unknown methods) are functions for which Infer didn't find any code. For example, it could be because the function belongs to a third-party library and we know only its signature, or because a function is made through a function pointer that Pulse wasn't able to resolve to a concrete function. In either case, Pulse will scramble the parts of the state reachable from the parameters of the call. In general, this helps avoid false positives but note that this may cause false negatives as well as false positives:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-c",children:"void unknown(int* p); // third-party code that does [*p = 5]\n // Infer doesn't have access to that code\n\nvoid false_negative() {\n int* x = (int*) malloc(sizeof(int));\n if (x) {\n // unknown call to x makes Pulse forget that x was allocated, in case it frees x\n unknown(x);\n }\n} // no memory leak reported: false negative!\n\nvoid false_positive(int *x) {\n unknown(x); // this sets *x to 5\n if (x != 5) {\n // unreachable\n int* p = NULL;\n *p = 42; // false positive reported here\n }\n}\n"})}),"\n",(0,l.jsx)(n.p,{children:"You can check if a given function called any unknown functions by inspecting its Pulse summary. For example, for the code above:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-console",children:"$ infer --pulse-only -- clang -c unknown_code.c\n No issues found\n$ infer debug --procedures --procedures-filter 'false_negative' --procedures-summary\n...\n skipped_calls={ unknown -> call to skipped function occurs here }\n"})}),"\n",(0,l.jsx)(n.h2,{id:"pulse-x-nullsafe",children:"Pulse x Nullsafe"}),"\n",(0,l.jsxs)(n.p,{children:["Nullsafe is a type checker for ",(0,l.jsx)(n.code,{children:"@Nullable"})," annotations for Java. Classes following the Nullsafe discipline are annotated with ",(0,l.jsx)(n.code,{children:"@Nullsafe"}),"."]}),"\n",(0,l.jsxs)(n.p,{children:["Consider the classes ",(0,l.jsx)(n.code,{children:"Person"})," and ",(0,l.jsx)(n.code,{children:"Registry"})," from the previous example. Assuming that class ",(0,l.jsx)(n.code,{children:"Person"})," is annotated with ",(0,l.jsx)(n.code,{children:"@Nullsafe"}),". In this case, we also annotate ",(0,l.jsx)(n.code,{children:"getEmergencyContact()"})," with ",(0,l.jsx)(n.code,{children:"@Nullable"}),", to make explicit that this method can return the ",(0,l.jsx)(n.code,{children:"null"})," value. There is still the risk that classes depending on ",(0,l.jsx)(n.code,{children:"Person"})," have Null dereferences. In this case, Pulse would report a Null dereference on ",(0,l.jsx)(n.code,{children:"Registry"}),". It could also be the case that class ",(0,l.jsx)(n.code,{children:"Registry"})," is annotated with ",(0,l.jsx)(n.code,{children:"@Nullsafe"}),". By default Pulse reports on ",(0,l.jsx)(n.code,{children:"@Nullsafe"})," files too, see the ",(0,l.jsx)(n.code,{children:"--pulse-nullsafe-report-npe"})," option (Facebook-specific: Pulse does not report on ",(0,l.jsx)(n.code,{children:"@Nullsafe"})," files)."]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-java",children:"@Nullsafe(Nullsafe.Mode.LOCAL)\nclass Person {\n Person emergencyContact;\n String address;\n\n @Nullable Person getEmergencyContact() {\n return this.emergencyContact;\n }\n}\n\nclass Registry {\n ... // Pulse reports here\n}\n"})}),"\n",(0,l.jsx)(n.h2,{id:"list-of-issue-types",children:"List of Issue Types"}),"\n",(0,l.jsx)(n.p,{children:"The following issue types are reported by this checker:"}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#bad_arg",children:"BAD_ARG"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#bad_arg_latent",children:"BAD_ARG_LATENT"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#bad_generator",children:"BAD_GENERATOR"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#bad_generator_latent",children:"BAD_GENERATOR_LATENT"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#bad_key",children:"BAD_KEY"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#bad_key_latent",children:"BAD_KEY_LATENT"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#bad_map",children:"BAD_MAP"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#bad_map_latent",children:"BAD_MAP_LATENT"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#bad_record",children:"BAD_RECORD"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#bad_record_latent",children:"BAD_RECORD_LATENT"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#bad_return",children:"BAD_RETURN"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#bad_return_latent",children:"BAD_RETURN_LATENT"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#compared_to_null_and_dereferenced",children:"COMPARED_TO_NULL_AND_DEREFERENCED"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#config_usage",children:"CONFIG_USAGE"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#constant_address_dereference",children:"CONSTANT_ADDRESS_DEREFERENCE"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#constant_address_dereference_latent",children:"CONSTANT_ADDRESS_DEREFERENCE_LATENT"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#data_flow_to_sink",children:"DATA_FLOW_TO_SINK"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#memory_leak_c",children:"MEMORY_LEAK_C"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#memory_leak_cpp",children:"MEMORY_LEAK_CPP"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#mutual_recursion_cycle",children:"MUTUAL_RECURSION_CYCLE"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#nil_block_call",children:"NIL_BLOCK_CALL"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#nil_block_call_latent",children:"NIL_BLOCK_CALL_LATENT"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#nil_insertion_into_collection",children:"NIL_INSERTION_INTO_COLLECTION"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#nil_insertion_into_collection_latent",children:"NIL_INSERTION_INTO_COLLECTION_LATENT"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#nil_messaging_to_non_pod",children:"NIL_MESSAGING_TO_NON_POD"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#nil_messaging_to_non_pod_latent",children:"NIL_MESSAGING_TO_NON_POD_LATENT"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#no_matching_branch_in_try",children:"NO_MATCHING_BRANCH_IN_TRY"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#no_matching_branch_in_try_latent",children:"NO_MATCHING_BRANCH_IN_TRY_LATENT"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#no_matching_case_clause",children:"NO_MATCHING_CASE_CLAUSE"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#no_matching_case_clause_latent",children:"NO_MATCHING_CASE_CLAUSE_LATENT"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#no_matching_else_clause",children:"NO_MATCHING_ELSE_CLAUSE"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#no_matching_else_clause_latent",children:"NO_MATCHING_ELSE_CLAUSE_LATENT"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#no_matching_function_clause",children:"NO_MATCHING_FUNCTION_CLAUSE"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#no_matching_function_clause_latent",children:"NO_MATCHING_FUNCTION_CLAUSE_LATENT"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#no_match_of_rhs",children:"NO_MATCH_OF_RHS"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#no_match_of_rhs_latent",children:"NO_MATCH_OF_RHS_LATENT"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#no_true_branch_in_if",children:"NO_TRUE_BRANCH_IN_IF"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#no_true_branch_in_if_latent",children:"NO_TRUE_BRANCH_IN_IF_LATENT"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#nullptr_dereference",children:"NULLPTR_DEREFERENCE"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#nullptr_dereference_in_nullsafe_class",children:"NULLPTR_DEREFERENCE_IN_NULLSAFE_CLASS"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#nullptr_dereference_in_nullsafe_class_latent",children:"NULLPTR_DEREFERENCE_IN_NULLSAFE_CLASS_LATENT"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#nullptr_dereference_latent",children:"NULLPTR_DEREFERENCE_LATENT"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#null_argument",children:"NULL_ARGUMENT"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#null_argument_latent",children:"NULL_ARGUMENT_LATENT"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#optional_empty_access",children:"OPTIONAL_EMPTY_ACCESS"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#optional_empty_access_latent",children:"OPTIONAL_EMPTY_ACCESS_LATENT"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#pulse_cannot_instantiate_abstract_class",children:"PULSE_CANNOT_INSTANTIATE_ABSTRACT_CLASS"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#pulse_const_refable",children:"PULSE_CONST_REFABLE"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#pulse_dict_missing_key",children:"PULSE_DICT_MISSING_KEY"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#pulse_dynamic_type_mismatch",children:"PULSE_DYNAMIC_TYPE_MISMATCH"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#pulse_readonly_shared_ptr_param",children:"PULSE_READONLY_SHARED_PTR_PARAM"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#pulse_reference_stability",children:"PULSE_REFERENCE_STABILITY"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#pulse_resource_leak",children:"PULSE_RESOURCE_LEAK"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#pulse_transitive_access",children:"PULSE_TRANSITIVE_ACCESS"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#pulse_unawaited_awaitable",children:"PULSE_UNAWAITED_AWAITABLE"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#pulse_unfinished_builder",children:"PULSE_UNFINISHED_BUILDER"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#pulse_uninitialized_const",children:"PULSE_UNINITIALIZED_CONST"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#pulse_uninitialized_method",children:"PULSE_UNINITIALIZED_METHOD"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#pulse_uninitialized_value",children:"PULSE_UNINITIALIZED_VALUE"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#pulse_unnecessary_copy",children:"PULSE_UNNECESSARY_COPY"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#pulse_unnecessary_copy_assignment",children:"PULSE_UNNECESSARY_COPY_ASSIGNMENT"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#pulse_unnecessary_copy_assignment_const",children:"PULSE_UNNECESSARY_COPY_ASSIGNMENT_CONST"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#pulse_unnecessary_copy_assignment_movable",children:"PULSE_UNNECESSARY_COPY_ASSIGNMENT_MOVABLE"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#pulse_unnecessary_copy_intermediate",children:"PULSE_UNNECESSARY_COPY_INTERMEDIATE"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#pulse_unnecessary_copy_intermediate_const",children:"PULSE_UNNECESSARY_COPY_INTERMEDIATE_CONST"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#pulse_unnecessary_copy_movable",children:"PULSE_UNNECESSARY_COPY_MOVABLE"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#pulse_unnecessary_copy_optional",children:"PULSE_UNNECESSARY_COPY_OPTIONAL"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#pulse_unnecessary_copy_optional_const",children:"PULSE_UNNECESSARY_COPY_OPTIONAL_CONST"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#pulse_unnecessary_copy_return",children:"PULSE_UNNECESSARY_COPY_RETURN"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#pulse_unnecessary_copy_thrift_assignment",children:"PULSE_UNNECESSARY_COPY_THRIFT_ASSIGNMENT"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#retain_cycle",children:"RETAIN_CYCLE"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#retain_cycle_no_weak_info",children:"RETAIN_CYCLE_NO_WEAK_INFO"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#sensitive_data_flow",children:"SENSITIVE_DATA_FLOW"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#stack_variable_address_escape",children:"STACK_VARIABLE_ADDRESS_ESCAPE"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#taint_error",children:"TAINT_ERROR"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#use_after_delete",children:"USE_AFTER_DELETE"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#use_after_delete_latent",children:"USE_AFTER_DELETE_LATENT"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#use_after_free",children:"USE_AFTER_FREE"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#use_after_free_latent",children:"USE_AFTER_FREE_LATENT"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#use_after_lifetime",children:"USE_AFTER_LIFETIME"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#use_after_lifetime_latent",children:"USE_AFTER_LIFETIME_LATENT"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#vector_invalidation",children:"VECTOR_INVALIDATION"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#vector_invalidation_latent",children:"VECTOR_INVALIDATION_LATENT"})}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,l.jsx)(n,{...e,children:(0,l.jsx)(o,{...e})}):o(e)}},8453:(e,n,s)=>{s.d(n,{R:()=>t,x:()=>c});var l=s(6540);const i={},r=l.createContext(i);function t(e){const n=l.useContext(r);return l.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:t(e.components),l.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[9437],{930:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>t,default:()=>h,frontMatter:()=>r,metadata:()=>c,toc:()=>d});var l=s(4848),i=s(8453);const r={title:"Pulse",description:"General-purpose memory and value analysis engine."},t=void 0,c={id:"checker-pulse",title:"Pulse",description:"General-purpose memory and value analysis engine.",source:"@site/docs/checker-pulse.md",sourceDirName:".",slug:"/checker-pulse",permalink:"/docs/next/checker-pulse",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"Pulse",description:"General-purpose memory and value analysis engine."},sidebar:"docs",previous:{title:"Parameter Not Null Checked",permalink:"/docs/next/checker-parameter-not-null-checked"},next:{title:"Purity",permalink:"/docs/next/checker-purity"}},a={},d=[{value:"What is Infer?",id:"what-is-infer",level:2},{value:"Latent Issues",id:"latent-issues",level:2},{value:"Unknown Functions",id:"unknown-functions",level:2},{value:"Pulse x Nullsafe",id:"pulse-x-nullsafe",level:2},{value:"List of Issue Types",id:"list-of-issue-types",level:2}];function o(e){const n={a:"a",code:"code",em:"em",h2:"h2",li:"li",p:"p",pre:"pre",ul:"ul",...(0,i.R)(),...e.components};return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(n.p,{children:"General-purpose memory and value analysis engine."}),"\n",(0,l.jsxs)(n.p,{children:["Activate with ",(0,l.jsx)(n.code,{children:"--pulse"}),"."]}),"\n",(0,l.jsx)(n.p,{children:"Supported languages:"}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:"C/C++/ObjC: Yes"}),"\n",(0,l.jsx)(n.li,{children:"C#/.Net: No"}),"\n",(0,l.jsx)(n.li,{children:"Erlang: Experimental"}),"\n",(0,l.jsx)(n.li,{children:"Hack: Yes"}),"\n",(0,l.jsx)(n.li,{children:"Java: Yes"}),"\n",(0,l.jsx)(n.li,{children:"Python: No"}),"\n"]}),"\n",(0,l.jsxs)(n.h2,{id:"what-is-infer",children:["What is Infer",":Pulse","?"]}),"\n",(0,l.jsxs)(n.p,{children:["Pulse is an interprocedural memory safety analysis. Pulse can detect, for instance, ",(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#nullptr_dereference",children:"Null dereferences"})," in Java. Errors are only reported when all conditions on the erroneous path are true regardless of input. Pulse should gradually replace the original ",(0,l.jsx)(n.a,{href:"/docs/next/checker-biabduction",children:"biabduction"})," analysis of Infer. An example of a Null dereference found by Pulse is given below."]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-java",children:"class Person {\n Person emergencyContact;\n String address;\n\n Person getEmergencyContact() {\n return this.emergencyContact;\n }\n}\n\nclass Registry {\n void create() {\n Person p = new Person();\n Person c = p.getEmergencyContact();\n // Null dereference here\n System.out.println(c.address);\n }\n\n void printContact(Person p) {\n // No null dereference, as we don't know anything about `p`\n System.out.println(p.getEmergencyContact().address);\n }\n}\n"})}),"\n",(0,l.jsx)(n.p,{children:"How to run pulse for Java:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"infer run --pulse -- javac Test.java\n"})}),"\n",(0,l.jsxs)(n.p,{children:["Pulse reports a Null dereference on this file on ",(0,l.jsx)(n.code,{children:"create()"}),", as it tries to access the field ",(0,l.jsx)(n.code,{children:"address"})," of object ",(0,l.jsx)(n.code,{children:"c"}),", and ",(0,l.jsx)(n.code,{children:"c"})," has value ",(0,l.jsx)(n.code,{children:"null"}),". In contrast, Pulse gives no report for ",(0,l.jsx)(n.code,{children:"printContact(Person p)"}),", as we cannot be sure that ",(0,l.jsx)(n.code,{children:"p.getEmergencyContact()"})," will return ",(0,l.jsx)(n.code,{children:"null"}),". But, thanks to the fact that the analysis is ",(0,l.jsx)(n.em,{children:"inter-procedural"}),", Pulse will report a Null dereference on calls to ",(0,l.jsx)(n.code,{children:"printContact(p)"})," when it detects that ",(0,l.jsx)(n.code,{children:"p"})," is null."]}),"\n",(0,l.jsx)(n.h2,{id:"latent-issues",children:"Latent Issues"}),"\n",(0,l.jsxs)(n.p,{children:["When an error can occur only on some values of the parameters of the current function, Pulse does not report an issue. Such issues are called ",(0,l.jsx)(n.em,{children:"latent"}),". But, if Pulse then sees a call site at which all the conditions for the error are satisfied then the error becomes ",(0,l.jsx)(n.em,{children:"manifest"})," and is reported. This example (in C) illustrates how latent issues are created and then reported when they become manifest:"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-c",children:"// for more realism, imagine that this function does other things as well\nvoid set_to_null_if_positive(int n, int* p) {\n if (n > 0) {\n p = NULL;\n }\n}\n\nvoid latent_null_dereference(int n, int* p) {\n set_to_null_if_positive(n, p);\n *p = 42; // NULL dereference! but only if n > 0 so no report yet\n}\n\nvoid manifest_error(int *p) {\n // no way to avoid the bug here => Pulse reports an error\n latent_null_dereference(1, p);\n}\n"})}),"\n",(0,l.jsx)(n.h2,{id:"unknown-functions",children:"Unknown Functions"}),"\n",(0,l.jsx)(n.p,{children:"In order to avoid false positives, Pulse makes optimistic assumptions about calls to unknown functions. Unknown functions (or unknown methods) are functions for which Infer didn't find any code. For example, it could be because the function belongs to a third-party library and we know only its signature, or because a function is made through a function pointer that Pulse wasn't able to resolve to a concrete function. In either case, Pulse will scramble the parts of the state reachable from the parameters of the call. In general, this helps avoid false positives but note that this may cause false negatives as well as false positives:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-c",children:"void unknown(int* p); // third-party code that does [*p = 5]\n // Infer doesn't have access to that code\n\nvoid false_negative() {\n int* x = (int*) malloc(sizeof(int));\n if (x) {\n // unknown call to x makes Pulse forget that x was allocated, in case it frees x\n unknown(x);\n }\n} // no memory leak reported: false negative!\n\nvoid false_positive(int *x) {\n unknown(x); // this sets *x to 5\n if (x != 5) {\n // unreachable\n int* p = NULL;\n *p = 42; // false positive reported here\n }\n}\n"})}),"\n",(0,l.jsx)(n.p,{children:"You can check if a given function called any unknown functions by inspecting its Pulse summary. For example, for the code above:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-console",children:"$ infer --pulse-only -- clang -c unknown_code.c\n No issues found\n$ infer debug --procedures --procedures-filter 'false_negative' --procedures-summary\n...\n skipped_calls={ unknown -> call to skipped function occurs here }\n"})}),"\n",(0,l.jsx)(n.h2,{id:"pulse-x-nullsafe",children:"Pulse x Nullsafe"}),"\n",(0,l.jsxs)(n.p,{children:["Nullsafe is a type checker for ",(0,l.jsx)(n.code,{children:"@Nullable"})," annotations for Java. Classes following the Nullsafe discipline are annotated with ",(0,l.jsx)(n.code,{children:"@Nullsafe"}),"."]}),"\n",(0,l.jsxs)(n.p,{children:["Consider the classes ",(0,l.jsx)(n.code,{children:"Person"})," and ",(0,l.jsx)(n.code,{children:"Registry"})," from the previous example. Assuming that class ",(0,l.jsx)(n.code,{children:"Person"})," is annotated with ",(0,l.jsx)(n.code,{children:"@Nullsafe"}),". In this case, we also annotate ",(0,l.jsx)(n.code,{children:"getEmergencyContact()"})," with ",(0,l.jsx)(n.code,{children:"@Nullable"}),", to make explicit that this method can return the ",(0,l.jsx)(n.code,{children:"null"})," value. There is still the risk that classes depending on ",(0,l.jsx)(n.code,{children:"Person"})," have Null dereferences. In this case, Pulse would report a Null dereference on ",(0,l.jsx)(n.code,{children:"Registry"}),". It could also be the case that class ",(0,l.jsx)(n.code,{children:"Registry"})," is annotated with ",(0,l.jsx)(n.code,{children:"@Nullsafe"}),". By default Pulse reports on ",(0,l.jsx)(n.code,{children:"@Nullsafe"})," files too, see the ",(0,l.jsx)(n.code,{children:"--pulse-nullsafe-report-npe"})," option (Facebook-specific: Pulse does not report on ",(0,l.jsx)(n.code,{children:"@Nullsafe"})," files)."]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-java",children:"@Nullsafe(Nullsafe.Mode.LOCAL)\nclass Person {\n Person emergencyContact;\n String address;\n\n @Nullable Person getEmergencyContact() {\n return this.emergencyContact;\n }\n}\n\nclass Registry {\n ... // Pulse reports here\n}\n"})}),"\n",(0,l.jsx)(n.h2,{id:"list-of-issue-types",children:"List of Issue Types"}),"\n",(0,l.jsx)(n.p,{children:"The following issue types are reported by this checker:"}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#bad_arg",children:"BAD_ARG"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#bad_arg_latent",children:"BAD_ARG_LATENT"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#bad_generator",children:"BAD_GENERATOR"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#bad_generator_latent",children:"BAD_GENERATOR_LATENT"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#bad_key",children:"BAD_KEY"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#bad_key_latent",children:"BAD_KEY_LATENT"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#bad_map",children:"BAD_MAP"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#bad_map_latent",children:"BAD_MAP_LATENT"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#bad_record",children:"BAD_RECORD"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#bad_record_latent",children:"BAD_RECORD_LATENT"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#bad_return",children:"BAD_RETURN"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#bad_return_latent",children:"BAD_RETURN_LATENT"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#compared_to_null_and_dereferenced",children:"COMPARED_TO_NULL_AND_DEREFERENCED"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#config_usage",children:"CONFIG_USAGE"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#constant_address_dereference",children:"CONSTANT_ADDRESS_DEREFERENCE"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#constant_address_dereference_latent",children:"CONSTANT_ADDRESS_DEREFERENCE_LATENT"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#data_flow_to_sink",children:"DATA_FLOW_TO_SINK"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#infinite_recursion",children:"INFINITE_RECURSION"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#memory_leak_c",children:"MEMORY_LEAK_C"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#memory_leak_cpp",children:"MEMORY_LEAK_CPP"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#mutual_recursion_cycle",children:"MUTUAL_RECURSION_CYCLE"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#nil_block_call",children:"NIL_BLOCK_CALL"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#nil_block_call_latent",children:"NIL_BLOCK_CALL_LATENT"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#nil_insertion_into_collection",children:"NIL_INSERTION_INTO_COLLECTION"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#nil_insertion_into_collection_latent",children:"NIL_INSERTION_INTO_COLLECTION_LATENT"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#nil_messaging_to_non_pod",children:"NIL_MESSAGING_TO_NON_POD"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#nil_messaging_to_non_pod_latent",children:"NIL_MESSAGING_TO_NON_POD_LATENT"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#no_matching_branch_in_try",children:"NO_MATCHING_BRANCH_IN_TRY"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#no_matching_branch_in_try_latent",children:"NO_MATCHING_BRANCH_IN_TRY_LATENT"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#no_matching_case_clause",children:"NO_MATCHING_CASE_CLAUSE"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#no_matching_case_clause_latent",children:"NO_MATCHING_CASE_CLAUSE_LATENT"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#no_matching_else_clause",children:"NO_MATCHING_ELSE_CLAUSE"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#no_matching_else_clause_latent",children:"NO_MATCHING_ELSE_CLAUSE_LATENT"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#no_matching_function_clause",children:"NO_MATCHING_FUNCTION_CLAUSE"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#no_matching_function_clause_latent",children:"NO_MATCHING_FUNCTION_CLAUSE_LATENT"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#no_match_of_rhs",children:"NO_MATCH_OF_RHS"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#no_match_of_rhs_latent",children:"NO_MATCH_OF_RHS_LATENT"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#no_true_branch_in_if",children:"NO_TRUE_BRANCH_IN_IF"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#no_true_branch_in_if_latent",children:"NO_TRUE_BRANCH_IN_IF_LATENT"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#nullptr_dereference",children:"NULLPTR_DEREFERENCE"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#nullptr_dereference_in_nullsafe_class",children:"NULLPTR_DEREFERENCE_IN_NULLSAFE_CLASS"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#nullptr_dereference_in_nullsafe_class_latent",children:"NULLPTR_DEREFERENCE_IN_NULLSAFE_CLASS_LATENT"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#nullptr_dereference_latent",children:"NULLPTR_DEREFERENCE_LATENT"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#null_argument",children:"NULL_ARGUMENT"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#null_argument_latent",children:"NULL_ARGUMENT_LATENT"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#optional_empty_access",children:"OPTIONAL_EMPTY_ACCESS"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#optional_empty_access_latent",children:"OPTIONAL_EMPTY_ACCESS_LATENT"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#pulse_cannot_instantiate_abstract_class",children:"PULSE_CANNOT_INSTANTIATE_ABSTRACT_CLASS"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#pulse_const_refable",children:"PULSE_CONST_REFABLE"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#pulse_dict_missing_key",children:"PULSE_DICT_MISSING_KEY"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#pulse_dynamic_type_mismatch",children:"PULSE_DYNAMIC_TYPE_MISMATCH"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#pulse_readonly_shared_ptr_param",children:"PULSE_READONLY_SHARED_PTR_PARAM"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#pulse_reference_stability",children:"PULSE_REFERENCE_STABILITY"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#pulse_resource_leak",children:"PULSE_RESOURCE_LEAK"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#pulse_transitive_access",children:"PULSE_TRANSITIVE_ACCESS"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#pulse_unawaited_awaitable",children:"PULSE_UNAWAITED_AWAITABLE"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#pulse_unfinished_builder",children:"PULSE_UNFINISHED_BUILDER"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#pulse_uninitialized_const",children:"PULSE_UNINITIALIZED_CONST"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#pulse_uninitialized_method",children:"PULSE_UNINITIALIZED_METHOD"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#pulse_uninitialized_value",children:"PULSE_UNINITIALIZED_VALUE"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#pulse_unnecessary_copy",children:"PULSE_UNNECESSARY_COPY"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#pulse_unnecessary_copy_assignment",children:"PULSE_UNNECESSARY_COPY_ASSIGNMENT"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#pulse_unnecessary_copy_assignment_const",children:"PULSE_UNNECESSARY_COPY_ASSIGNMENT_CONST"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#pulse_unnecessary_copy_assignment_movable",children:"PULSE_UNNECESSARY_COPY_ASSIGNMENT_MOVABLE"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#pulse_unnecessary_copy_intermediate",children:"PULSE_UNNECESSARY_COPY_INTERMEDIATE"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#pulse_unnecessary_copy_intermediate_const",children:"PULSE_UNNECESSARY_COPY_INTERMEDIATE_CONST"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#pulse_unnecessary_copy_movable",children:"PULSE_UNNECESSARY_COPY_MOVABLE"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#pulse_unnecessary_copy_optional",children:"PULSE_UNNECESSARY_COPY_OPTIONAL"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#pulse_unnecessary_copy_optional_const",children:"PULSE_UNNECESSARY_COPY_OPTIONAL_CONST"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#pulse_unnecessary_copy_return",children:"PULSE_UNNECESSARY_COPY_RETURN"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#pulse_unnecessary_copy_thrift_assignment",children:"PULSE_UNNECESSARY_COPY_THRIFT_ASSIGNMENT"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#retain_cycle",children:"RETAIN_CYCLE"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#retain_cycle_no_weak_info",children:"RETAIN_CYCLE_NO_WEAK_INFO"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#sensitive_data_flow",children:"SENSITIVE_DATA_FLOW"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#stack_variable_address_escape",children:"STACK_VARIABLE_ADDRESS_ESCAPE"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#taint_error",children:"TAINT_ERROR"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#use_after_delete",children:"USE_AFTER_DELETE"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#use_after_delete_latent",children:"USE_AFTER_DELETE_LATENT"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#use_after_free",children:"USE_AFTER_FREE"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#use_after_free_latent",children:"USE_AFTER_FREE_LATENT"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#use_after_lifetime",children:"USE_AFTER_LIFETIME"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#use_after_lifetime_latent",children:"USE_AFTER_LIFETIME_LATENT"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#vector_invalidation",children:"VECTOR_INVALIDATION"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/docs/next/all-issue-types#vector_invalidation_latent",children:"VECTOR_INVALIDATION_LATENT"})}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,l.jsx)(n,{...e,children:(0,l.jsx)(o,{...e})}):o(e)}},8453:(e,n,s)=>{s.d(n,{R:()=>t,x:()=>c});var l=s(6540);const i={},r=l.createContext(i);function t(e){const n=l.useContext(r);return l.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:t(e.components),l.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c359af60.1278ce61.js b/assets/js/c359af60.1278ce61.js deleted file mode 100644 index dcbf7db0074..00000000000 --- a/assets/js/c359af60.1278ce61.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[2316],{28:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>t,metadata:()=>l,toc:()=>o});var r=s(4848),i=s(8453);const t={title:"List of all issue types"},a=void 0,l={id:"all-issue-types",title:"List of all issue types",description:"Here is an overview of the issue types currently reported by Infer.",source:"@site/docs/all-issue-types.md",sourceDirName:".",slug:"/all-issue-types",permalink:"/docs/next/all-issue-types",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"List of all issue types"},sidebar:"docs",previous:{title:"List of all categories of issue types",permalink:"/docs/next/all-categories"},next:{title:"Annotation Reachability",permalink:"/docs/next/checker-annotation-reachability"}},c={},o=[{value:"ARBITRARY_CODE_EXECUTION_UNDER_LOCK",id:"arbitrary_code_execution_under_lock",level:2},{value:"BAD_ARG",id:"bad_arg",level:2},{value:"BAD_ARG_LATENT",id:"bad_arg_latent",level:2},{value:"BAD_GENERATOR",id:"bad_generator",level:2},{value:"BAD_GENERATOR_LATENT",id:"bad_generator_latent",level:2},{value:"BAD_KEY",id:"bad_key",level:2},{value:"BAD_KEY_LATENT",id:"bad_key_latent",level:2},{value:"BAD_MAP",id:"bad_map",level:2},{value:"BAD_MAP_LATENT",id:"bad_map_latent",level:2},{value:"BAD_RECORD",id:"bad_record",level:2},{value:"BAD_RECORD_LATENT",id:"bad_record_latent",level:2},{value:"BAD_RETURN",id:"bad_return",level:2},{value:"BAD_RETURN_LATENT",id:"bad_return_latent",level:2},{value:"BIABDUCTION_MEMORY_LEAK",id:"biabduction_memory_leak",level:2},{value:"BIABDUCTION_RETAIN_CYCLE",id:"biabduction_retain_cycle",level:2},{value:"BLOCK_PARAMETER_NOT_NULL_CHECKED",id:"block_parameter_not_null_checked",level:2},{value:"BUFFER_OVERRUN_L1",id:"buffer_overrun_l1",level:2},{value:"BUFFER_OVERRUN_L2",id:"buffer_overrun_l2",level:2},{value:"BUFFER_OVERRUN_L3",id:"buffer_overrun_l3",level:2},{value:"BUFFER_OVERRUN_L4",id:"buffer_overrun_l4",level:2},{value:"BUFFER_OVERRUN_L5",id:"buffer_overrun_l5",level:2},{value:"BUFFER_OVERRUN_S2",id:"buffer_overrun_s2",level:2},{value:"BUFFER_OVERRUN_U5",id:"buffer_overrun_u5",level:2},{value:"CAPTURED_STRONG_SELF",id:"captured_strong_self",level:2},{value:"CHECKERS_ALLOCATES_MEMORY",id:"checkers_allocates_memory",level:2},{value:"CHECKERS_ANNOTATION_REACHABILITY_ERROR",id:"checkers_annotation_reachability_error",level:2},{value:"CHECKERS_CALLS_EXPENSIVE_METHOD",id:"checkers_calls_expensive_method",level:2},{value:"CHECKERS_EXPENSIVE_OVERRIDES_UNANNOTATED",id:"checkers_expensive_overrides_unannotated",level:2},{value:"CHECKERS_FRAGMENT_RETAINS_VIEW",id:"checkers_fragment_retains_view",level:2},{value:"COMPARED_TO_NULL_AND_DEREFERENCED",id:"compared_to_null_and_dereferenced",level:2},{value:"CONFIG_IMPACT",id:"config_impact",level:2},{value:"CONFIG_IMPACT_STRICT",id:"config_impact_strict",level:2},{value:"CONFIG_USAGE",id:"config_usage",level:2},{value:"CONSTANT_ADDRESS_DEREFERENCE",id:"constant_address_dereference",level:2},{value:"CONSTANT_ADDRESS_DEREFERENCE_LATENT",id:"constant_address_dereference_latent",level:2},{value:"CXX_REF_CAPTURED_IN_BLOCK",id:"cxx_ref_captured_in_block",level:2},{value:"CXX_STRING_CAPTURED_IN_BLOCK",id:"cxx_string_captured_in_block",level:2},{value:"DANGLING_POINTER_DEREFERENCE",id:"dangling_pointer_dereference",level:2},{value:"DATA_FLOW_TO_SINK",id:"data_flow_to_sink",level:2},{value:"DEADLOCK",id:"deadlock",level:2},{value:"DEAD_STORE",id:"dead_store",level:2},{value:"DIVIDE_BY_ZERO",id:"divide_by_zero",level:2},{value:"EMPTY_VECTOR_ACCESS",id:"empty_vector_access",level:2},{value:"EXECUTION_TIME_COMPLEXITY_INCREASE",id:"execution_time_complexity_increase",level:2},{value:"EXECUTION_TIME_COMPLEXITY_INCREASE_UI_THREAD",id:"execution_time_complexity_increase_ui_thread",level:2},{value:"EXECUTION_TIME_UNREACHABLE_AT_EXIT",id:"execution_time_unreachable_at_exit",level:2},{value:"EXPENSIVE_EXECUTION_TIME",id:"expensive_execution_time",level:2},{value:"EXPENSIVE_LOOP_INVARIANT_CALL",id:"expensive_loop_invariant_call",level:2},{value:"GUARDEDBY_VIOLATION",id:"guardedby_violation",level:2},{value:"IMPURE_FUNCTION",id:"impure_function",level:2},{value:"INEFFICIENT_KEYSET_ITERATOR",id:"inefficient_keyset_iterator",level:2},{value:"INFERBO_ALLOC_IS_BIG",id:"inferbo_alloc_is_big",level:2},{value:"INFERBO_ALLOC_IS_NEGATIVE",id:"inferbo_alloc_is_negative",level:2},{value:"INFERBO_ALLOC_IS_ZERO",id:"inferbo_alloc_is_zero",level:2},{value:"INFERBO_ALLOC_MAY_BE_BIG",id:"inferbo_alloc_may_be_big",level:2},{value:"INFERBO_ALLOC_MAY_BE_NEGATIVE",id:"inferbo_alloc_may_be_negative",level:2},{value:"INFINITE_EXECUTION_TIME",id:"infinite_execution_time",level:2},{value:"Example 1: T due to expressivity",id:"example-1-t-due-to-expressivity",level:3},{value:"Example 2: T due to unmodeled calls",id:"example-2-t-due-to-unmodeled-calls",level:3},{value:"Example 3: T due to calling another T-costed function",id:"example-3-t-due-to-calling-another-t-costed-function",level:3},{value:"INTEGER_OVERFLOW_L1",id:"integer_overflow_l1",level:2},{value:"INTEGER_OVERFLOW_L2",id:"integer_overflow_l2",level:2},{value:"INTEGER_OVERFLOW_L5",id:"integer_overflow_l5",level:2},{value:"INTEGER_OVERFLOW_U5",id:"integer_overflow_u5",level:2},{value:"INTERFACE_NOT_THREAD_SAFE",id:"interface_not_thread_safe",level:2},{value:"INVALID_SIL",id:"invalid_sil",level:2},{value:"INVARIANT_CALL",id:"invariant_call",level:2},{value:"IPC_ON_UI_THREAD",id:"ipc_on_ui_thread",level:2},{value:"LAB_RESOURCE_LEAK",id:"lab_resource_leak",level:2},{value:"LINEAGE_FLOW",id:"lineage_flow",level:2},{value:"LOCKLESS_VIOLATION",id:"lockless_violation",level:2},{value:"LOCK_CONSISTENCY_VIOLATION",id:"lock_consistency_violation",level:2},{value:"Fixing Lock Consistency Violation reports",id:"fixing-lock-consistency-violation-reports",level:3},{value:"MEMORY_LEAK_C",id:"memory_leak_c",level:2},{value:"Memory leak in C",id:"memory-leak-in-c",level:3},{value:"Memory leak in Objective-C",id:"memory-leak-in-objective-c",level:3},{value:"MEMORY_LEAK_CPP",id:"memory_leak_cpp",level:2},{value:"MISSING_REQUIRED_PROP",id:"missing_required_prop",level:2},{value:"Examples",id:"examples",level:2},{value:"MIXED_SELF_WEAKSELF",id:"mixed_self_weakself",level:2},{value:"MODIFIES_IMMUTABLE",id:"modifies_immutable",level:2},{value:"MULTIPLE_WEAKSELF",id:"multiple_weakself",level:2},{value:"MUTUAL_RECURSION_CYCLE",id:"mutual_recursion_cycle",level:2},{value:"NIL_BLOCK_CALL",id:"nil_block_call",level:2},{value:"NIL_BLOCK_CALL_LATENT",id:"nil_block_call_latent",level:2},{value:"NIL_INSERTION_INTO_COLLECTION",id:"nil_insertion_into_collection",level:2},{value:"Arrays",id:"arrays",level:3},{value:"Dictionaries",id:"dictionaries",level:3},{value:"NIL_INSERTION_INTO_COLLECTION_LATENT",id:"nil_insertion_into_collection_latent",level:2},{value:"NIL_MESSAGING_TO_NON_POD",id:"nil_messaging_to_non_pod",level:2},{value:"NIL_MESSAGING_TO_NON_POD_LATENT",id:"nil_messaging_to_non_pod_latent",level:2},{value:"NO_MATCHING_BRANCH_IN_TRY",id:"no_matching_branch_in_try",level:2},{value:"NO_MATCHING_BRANCH_IN_TRY_LATENT",id:"no_matching_branch_in_try_latent",level:2},{value:"NO_MATCHING_CASE_CLAUSE",id:"no_matching_case_clause",level:2},{value:"NO_MATCHING_CASE_CLAUSE_LATENT",id:"no_matching_case_clause_latent",level:2},{value:"NO_MATCHING_ELSE_CLAUSE",id:"no_matching_else_clause",level:2},{value:"NO_MATCHING_ELSE_CLAUSE_LATENT",id:"no_matching_else_clause_latent",level:2},{value:"NO_MATCHING_FUNCTION_CLAUSE",id:"no_matching_function_clause",level:2},{value:"NO_MATCHING_FUNCTION_CLAUSE_LATENT",id:"no_matching_function_clause_latent",level:2},{value:"NO_MATCH_OF_RHS",id:"no_match_of_rhs",level:2},{value:"NO_MATCH_OF_RHS_LATENT",id:"no_match_of_rhs_latent",level:2},{value:"NO_TRUE_BRANCH_IN_IF",id:"no_true_branch_in_if",level:2},{value:"NO_TRUE_BRANCH_IN_IF_LATENT",id:"no_true_branch_in_if_latent",level:2},{value:"NSSTRING_INTERNAL_PTR_CAPTURED_IN_BLOCK",id:"nsstring_internal_ptr_captured_in_block",level:2},{value:"NULLPTR_DEREFERENCE",id:"nullptr_dereference",level:2},{value:"Null dereference in Java",id:"null-dereference-in-java",level:3},{value:"Null dereference in C",id:"null-dereference-in-c",level:3},{value:"Null dereference in Objective-C",id:"null-dereference-in-objective-c",level:3},{value:"NULLPTR_DEREFERENCE_IN_NULLSAFE_CLASS",id:"nullptr_dereference_in_nullsafe_class",level:2},{value:"Null dereference in Java",id:"null-dereference-in-java-1",level:3},{value:"Null dereference in C",id:"null-dereference-in-c-1",level:3},{value:"Null dereference in Objective-C",id:"null-dereference-in-objective-c-1",level:3},{value:"NULLPTR_DEREFERENCE_IN_NULLSAFE_CLASS_LATENT",id:"nullptr_dereference_in_nullsafe_class_latent",level:2},{value:"NULLPTR_DEREFERENCE_LATENT",id:"nullptr_dereference_latent",level:2},{value:"NULL_ARGUMENT",id:"null_argument",level:2},{value:"NULL_ARGUMENT_LATENT",id:"null_argument_latent",level:2},{value:"NULL_DEREFERENCE",id:"null_dereference",level:2},{value:"OPTIONAL_EMPTY_ACCESS",id:"optional_empty_access",level:2},{value:"OPTIONAL_EMPTY_ACCESS_LATENT",id:"optional_empty_access_latent",level:2},{value:"PREMATURE_NIL_TERMINATION_ARGUMENT",id:"premature_nil_termination_argument",level:2},{value:"PULSE_CANNOT_INSTANTIATE_ABSTRACT_CLASS",id:"pulse_cannot_instantiate_abstract_class",level:2},{value:"PULSE_CONST_REFABLE",id:"pulse_const_refable",level:2},{value:"PULSE_DICT_MISSING_KEY",id:"pulse_dict_missing_key",level:2},{value:"PULSE_DYNAMIC_TYPE_MISMATCH",id:"pulse_dynamic_type_mismatch",level:2},{value:"PULSE_READONLY_SHARED_PTR_PARAM",id:"pulse_readonly_shared_ptr_param",level:2},{value:"PULSE_REFERENCE_STABILITY",id:"pulse_reference_stability",level:2},{value:"PULSE_RESOURCE_LEAK",id:"pulse_resource_leak",level:2},{value:"PULSE_TRANSITIVE_ACCESS",id:"pulse_transitive_access",level:2},{value:"PULSE_UNAWAITED_AWAITABLE",id:"pulse_unawaited_awaitable",level:2},{value:"PULSE_UNFINISHED_BUILDER",id:"pulse_unfinished_builder",level:2},{value:"PULSE_UNINITIALIZED_CONST",id:"pulse_uninitialized_const",level:2},{value:"PULSE_UNINITIALIZED_METHOD",id:"pulse_uninitialized_method",level:2},{value:"PULSE_UNINITIALIZED_VALUE",id:"pulse_uninitialized_value",level:2},{value:"PULSE_UNNECESSARY_COPY",id:"pulse_unnecessary_copy",level:2},{value:"PULSE_UNNECESSARY_COPY_ASSIGNMENT",id:"pulse_unnecessary_copy_assignment",level:2},{value:"PULSE_UNNECESSARY_COPY_ASSIGNMENT_CONST",id:"pulse_unnecessary_copy_assignment_const",level:2},{value:"PULSE_UNNECESSARY_COPY_ASSIGNMENT_MOVABLE",id:"pulse_unnecessary_copy_assignment_movable",level:2},{value:"PULSE_UNNECESSARY_COPY_INTERMEDIATE",id:"pulse_unnecessary_copy_intermediate",level:2},{value:"PULSE_UNNECESSARY_COPY_INTERMEDIATE_CONST",id:"pulse_unnecessary_copy_intermediate_const",level:2},{value:"PULSE_UNNECESSARY_COPY_MOVABLE",id:"pulse_unnecessary_copy_movable",level:2},{value:"PULSE_UNNECESSARY_COPY_OPTIONAL",id:"pulse_unnecessary_copy_optional",level:2},{value:"PULSE_UNNECESSARY_COPY_OPTIONAL_CONST",id:"pulse_unnecessary_copy_optional_const",level:2},{value:"PULSE_UNNECESSARY_COPY_RETURN",id:"pulse_unnecessary_copy_return",level:2},{value:"PULSE_UNNECESSARY_COPY_THRIFT_ASSIGNMENT",id:"pulse_unnecessary_copy_thrift_assignment",level:2},{value:"PURE_FUNCTION",id:"pure_function",level:2},{value:"REGEX_OP_ON_UI_THREAD",id:"regex_op_on_ui_thread",level:2},{value:"RESOURCE_LEAK",id:"resource_leak",level:2},{value:"Resource leak in C",id:"resource-leak-in-c",level:3},{value:"Resource leak in Java",id:"resource-leak-in-java",level:3},{value:"Basics and Standard Idiom",id:"basics-and-standard-idiom",level:3},{value:"Multiple Resources Bugs",id:"multiple-resources-bugs",level:4},{value:"Nested_Allocations",id:"nested_allocations",level:3},{value:"Allocation of JSonParser and Cursor resources",id:"allocation-of-jsonparser-and-cursor-resources",level:3},{value:"Escaping resources and exceptions",id:"escaping-resources-and-exceptions",level:3},{value:"Java 7's try-with-resources",id:"java-7s-try-with-resources",level:3},{value:"RETAIN_CYCLE",id:"retain_cycle",level:2},{value:"RETAIN_CYCLE_NO_WEAK_INFO",id:"retain_cycle_no_weak_info",level:2},{value:"SCOPE_LEAKAGE",id:"scope_leakage",level:2},{value:"SELF_IN_BLOCK_PASSED_TO_INIT",id:"self_in_block_passed_to_init",level:2},{value:"SENSITIVE_DATA_FLOW",id:"sensitive_data_flow",level:2},{value:"STACK_VARIABLE_ADDRESS_ESCAPE",id:"stack_variable_address_escape",level:2},{value:"STARVATION",id:"starvation",level:2},{value:"STATIC_CONSTRUCTOR_STALL",id:"static_constructor_stall",level:2},{value:"STATIC_INITIALIZATION_ORDER_FIASCO",id:"static_initialization_order_fiasco",level:2},{value:"STRICT_MODE_VIOLATION",id:"strict_mode_violation",level:2},{value:"STRONG_SELF_NOT_CHECKED",id:"strong_self_not_checked",level:2},{value:"TAINT_ERROR",id:"taint_error",level:2},{value:"THREAD_SAFETY_VIOLATION",id:"thread_safety_violation",level:2},{value:"Thread-safety: What is a data race",id:"thread-safety-what-is-a-data-race",level:3},{value:"Thread-safety: Potential fixes",id:"thread-safety-potential-fixes",level:3},{value:"Thread-safety: Conditions checked before reporting",id:"thread-safety-conditions-checked-before-reporting",level:3},{value:"Thread-safety: Thread annotations recognized by RacerD",id:"thread-safety-thread-annotations-recognized-by-racerd",level:3},{value:"Thread-safety: Other annotations and what they do",id:"thread-safety-other-annotations-and-what-they-do",level:3},{value:"TOPL_ERROR",id:"topl_error",level:2},{value:"TOPL_ERROR_LATENT",id:"topl_error_latent",level:2},{value:"USE_AFTER_DELETE",id:"use_after_delete",level:2},{value:"USE_AFTER_DELETE_LATENT",id:"use_after_delete_latent",level:2},{value:"USE_AFTER_FREE",id:"use_after_free",level:2},{value:"USE_AFTER_FREE_LATENT",id:"use_after_free_latent",level:2},{value:"USE_AFTER_LIFETIME",id:"use_after_lifetime",level:2},{value:"USE_AFTER_LIFETIME_LATENT",id:"use_after_lifetime_latent",level:2},{value:"VECTOR_INVALIDATION",id:"vector_invalidation",level:2},{value:"VECTOR_INVALIDATION_LATENT",id:"vector_invalidation_latent",level:2},{value:"WEAK_SELF_IN_NO_ESCAPE_BLOCK",id:"weak_self_in_no_escape_block",level:2}];function d(e){const n={a:"a",code:"code",em:"em",h2:"h2",h3:"h3",h4:"h4",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.p,{children:"Here is an overview of the issue types currently reported by Infer."}),"\n",(0,r.jsx)(n.h2,{id:"arbitrary_code_execution_under_lock",children:"ARBITRARY_CODE_EXECUTION_UNDER_LOCK"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Arbitrary Code Execution Under lock" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-starvation",children:"starvation"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"A call that may execute arbitrary code (such as registered, or chained, callbacks) is made while holding a lock.\nThis code may deadlock whenever the callbacks obtain locks themselves, so it is an unsafe pattern."}),"\n",(0,r.jsx)(n.p,{children:"Example:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:" SettableFuture future = null;\n\n public void callFutureSet() {\n future.set(null);\n }\n\n // synchronized means it's taking a lock implicitly\n public synchronized void example_of_bad_pattern() {\n callFutureSet(); // <- issue reported here\n }\n\n // If the call is made while holding multiple locks, the warning\n // will be issued only at the innermost lock acquisition. Here we\n // report in example_of_bad_pattern but we won't report below.\n public void nested_bad_pattern_no_report(Object o) {\n synchronized (o) {\n example_of_bad_pattern(); // <- no issue reported\n }\n }\n"})}),"\n",(0,r.jsx)(n.h2,{id:"bad_arg",children:"BAD_ARG"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "Bad Arg" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["Bad arg in Erlang: Reports an error when the type of an argument is wrong or the argument is badly formed. Corresponds to the ",(0,r.jsx)(n.code,{children:"badarg"})," error in the Erlang runtime."]}),"\n",(0,r.jsxs)(n.p,{children:["For example, trying to concatenate the number ",(0,r.jsx)(n.code,{children:"3"})," with the list ",(0,r.jsx)(n.code,{children:"[1,2]"})," gives ",(0,r.jsx)(n.code,{children:"badarg"})," error because ",(0,r.jsx)(n.code,{children:"3"})," is not a list."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-erlang",children:"f() ->\n 3 ++ [1,2]. // badarg error\n"})}),"\n",(0,r.jsxs)(n.p,{children:["Note that although the first argument needs to be a list, the second argument may not be a list.\nFor instance, concatenating [1,2] with the number ",(0,r.jsx)(n.code,{children:"3"})," raises no error in Erlang."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-erlang",children:"g() ->\n [1,2] ++ 3. // no error. Result: [1,2|3]\n"})}),"\n",(0,r.jsx)(n.h2,{id:"bad_arg_latent",children:"BAD_ARG_LATENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "Bad Arg Latent" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A latent ",(0,r.jsx)(n.a,{href:"#bad_arg",children:"BAD_ARG"}),". See the ",(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse#latent-issues",children:"documentation on Pulse latent issues"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"bad_generator",children:"BAD_GENERATOR"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "Bad Generator" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["Bad generator in Erlang: Reports an error when a wrong type is used in a generator. Corresponds to the ",(0,r.jsx)(n.code,{children:"bad_generator"})," error in the Erlang runtime."]}),"\n",(0,r.jsx)(n.p,{children:"For example:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-erlang",children:"list_instead_of_map() ->\n M = [],\n [{K, V} || K := V <- M]\n"})}),"\n",(0,r.jsx)(n.h2,{id:"bad_generator_latent",children:"BAD_GENERATOR_LATENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "Bad Generator Latent" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A latent ",(0,r.jsx)(n.a,{href:"#bad_generator",children:"BAD_GENERATOR"}),". See the ",(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse#latent-issues",children:"documentation on Pulse latent issues"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"bad_key",children:"BAD_KEY"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "Bad Key" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["Bad key in Erlang: Reports an error when trying to access or update a non-existing key in a map. Corresponds to the ",(0,r.jsx)(n.code,{children:"{badkey,K}"})," error in the Erlang runtime."]}),"\n",(0,r.jsxs)(n.p,{children:["For example, trying to update the key ",(0,r.jsx)(n.code,{children:"2"})," in ",(0,r.jsx)(n.code,{children:"M"})," gives ",(0,r.jsx)(n.code,{children:"{badkey,2}"})," error because ",(0,r.jsx)(n.code,{children:"2"})," is not present as a key in ",(0,r.jsx)(n.code,{children:"M"}),"."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-erlang",children:"f() ->\n M = #{},\n M#{2 := 3}.\n"})}),"\n",(0,r.jsx)(n.p,{children:"Note that maps currently use a recency abstraction, meaning that only the most recent key/value is tracked.\nTherefore, if a map is non-empty and we try to access a key other than the one we track, we just assume that it is there to avoid false positives."}),"\n",(0,r.jsx)(n.h2,{id:"bad_key_latent",children:"BAD_KEY_LATENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "Bad Key Latent" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A latent ",(0,r.jsx)(n.a,{href:"#bad_key",children:"BAD_KEY"}),". See the ",(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse#latent-issues",children:"documentation on Pulse latent issues"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"bad_map",children:"BAD_MAP"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "Bad Map" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["Bad map in Erlang: Reports an error when trying to access or update a key for a term that is not a map. Corresponds to the ",(0,r.jsx)(n.code,{children:"{badmap,...}"})," error in the Erlang runtime."]}),"\n",(0,r.jsxs)(n.p,{children:["For example, trying to update ",(0,r.jsx)(n.code,{children:"L"})," as if it was a map gives ",(0,r.jsx)(n.code,{children:"{badmap,[1,2,3]}"})," error because ",(0,r.jsx)(n.code,{children:"L"})," is actually a list (",(0,r.jsx)(n.code,{children:"[1,2,3]"}),")."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-erlang",children:"f() ->\n L = [1,2,3],\n L#{1 => 2}.\n"})}),"\n",(0,r.jsx)(n.h2,{id:"bad_map_latent",children:"BAD_MAP_LATENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "Bad Map Latent" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A latent ",(0,r.jsx)(n.a,{href:"#bad_map",children:"BAD_MAP"}),". See the ",(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse#latent-issues",children:"documentation on Pulse latent issues"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"bad_record",children:"BAD_RECORD"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "Bad Record" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["Bad record in Erlang: Reports an error when trying to access or update a record with the wrong name. Corresponds to the ",(0,r.jsx)(n.code,{children:"{badrecord,Name}"})," error in the Erlang runtime."]}),"\n",(0,r.jsxs)(n.p,{children:["For example, accessing ",(0,r.jsx)(n.code,{children:"R"})," as a ",(0,r.jsx)(n.code,{children:"person"})," record gives ",(0,r.jsx)(n.code,{children:"{badrecord,person}"})," error because ",(0,r.jsx)(n.code,{children:"R"})," is ",(0,r.jsx)(n.code,{children:"rabbit"})," (even though both share the ",(0,r.jsx)(n.code,{children:"name"})," field)."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-erlang",children:'-record(person, {name, phone}).\n-record(rabbit, {name, color}).\n\nf() ->\n R = #rabbit{name = "Bunny", color = "Brown"},\n R#person.name.\n'})}),"\n",(0,r.jsx)(n.h2,{id:"bad_record_latent",children:"BAD_RECORD_LATENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "Bad Record Latent" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A latent ",(0,r.jsx)(n.a,{href:"#bad_record",children:"BAD_RECORD"}),". See the ",(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse#latent-issues",children:"documentation on Pulse latent issues"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"bad_return",children:"BAD_RETURN"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Bad Return" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"Bad return in Erlang: The dynamic type of a returned value disagrees with the static type given in the spec."}),"\n",(0,r.jsx)(n.p,{children:"For example, this function returns an integer, while the spec says it returns an atom."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-erlang",children:"-spec f() -> atom().\nf() -> 1.\n"})}),"\n",(0,r.jsxs)(n.p,{children:["Note that this will ",(0,r.jsx)(n.em,{children:"not"})," lead to a runtime error when running the Erlang program."]}),"\n",(0,r.jsx)(n.h2,{id:"bad_return_latent",children:"BAD_RETURN_LATENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Bad Return Latent" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A latent ",(0,r.jsx)(n.a,{href:"#bad_return",children:"BAD_RETURN"}),". See the ",(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse#latent-issues",children:"documentation on Pulse latent issues"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"biabduction_memory_leak",children:"BIABDUCTION_MEMORY_LEAK"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#resource-leak",children:"Resource leak"}),'. Reported as "Memory Leak" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-biabduction",children:"biabduction"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["See ",(0,r.jsx)(n.a,{href:"#memory_leak_c",children:"MEMORY_LEAK_C"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"biabduction_retain_cycle",children:"BIABDUCTION_RETAIN_CYCLE"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#resource-leak",children:"Resource leak"}),'. Reported as "Retain Cycle" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-biabduction",children:"biabduction"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["See ",(0,r.jsx)(n.a,{href:"#retain_cycle",children:"RETAIN_CYCLE"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"block_parameter_not_null_checked",children:"BLOCK_PARAMETER_NOT_NULL_CHECKED"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#null-pointer-dereference",children:"Null pointer dereference"}),'. Reported as "Block Parameter Not Null Checked" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-parameter-not-null-checked",children:"parameter-not-null-checked"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This error type is reported only in Objective-C/Objective-C++. It happens when a method has a block as a parameter,\nand the block is executed in the method's body without checking it for ",(0,r.jsx)(n.code,{children:"nil"})," first. If a ",(0,r.jsx)(n.code,{children:"nil"})," block is passed to\nthe method, then this will cause a crash. For example:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objectivec",children:"- (void)uploadTaskWithRequest:(NSURLRequest*)urlRequest\n fromFile:(NSURL*)fileURL\n delegate:(id)delegate\n delegateQueue:(NSOperationQueue*)delegateQueue\n completion:(void (^)())completion {\n ...\n completion();\n}\n"})}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"Action"}),":\nPossible solutions are adding a check for ",(0,r.jsx)(n.code,{children:"nil"}),", or making sure that the method\nis not ever called with ",(0,r.jsx)(n.code,{children:"nil"}),". When an argument will never be ",(0,r.jsx)(n.code,{children:"nil"}),", you can add\nthe annotation ",(0,r.jsx)(n.code,{children:"nonnull"})," to the argument's type, to tell Infer (and the type\nsystem), that the argument won't be ",(0,r.jsx)(n.code,{children:"nil"}),". This will silence the warning."]}),"\n",(0,r.jsx)(n.h2,{id:"buffer_overrun_l1",children:"BUFFER_OVERRUN_L1"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Buffer Overrun L1" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-bufferoverrun",children:"bufferoverrun"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"This is reported when outside of buffer bound is accessed. It can corrupt memory and may introduce\nsecurity issues in C/C++."}),"\n",(0,r.jsxs)(n.p,{children:["For example, ",(0,r.jsx)(n.code,{children:"int a[3]; a[5] = 42;"})," generates a ",(0,r.jsx)(n.code,{children:"BUFFER_OVERRUN_L1"})," on ",(0,r.jsx)(n.code,{children:"a[5] = 42;"}),"."]}),"\n",(0,r.jsx)(n.p,{children:'Buffer overrun reports fall into several "buckets" corresponding to the expected precision of the\nreport. The higher the number, the more likely it is to be a false positive.'}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"L1"}),": The most faithful report, when it ",(0,r.jsx)(n.em,{children:"must"})," be unsafe. For example, array size: ",(0,r.jsx)(n.code,{children:"[3,3]"}),",\noffset: ",(0,r.jsx)(n.code,{children:"[5,5]"}),"."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"L2"}),": Less faithful report than ",(0,r.jsx)(n.code,{children:"L1"}),", when it ",(0,r.jsx)(n.em,{children:"may"})," be unsafe. For example, array size:",(0,r.jsx)(n.code,{children:"[3,3]"}),",\noffset: ",(0,r.jsx)(n.code,{children:"[0,5]"}),". Note that the offset may be a safe value in the real execution, i.e. safe when\n0, 1, or 2; unsafe when 3, 4, or 5."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"L5"}),": The least faithful report, when there is an interval top. For example, array size:\n",(0,r.jsx)(n.code,{children:"[3,3]"}),", offset: ",(0,r.jsx)(n.code,{children:"[-oo,+oo]"}),"."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"L4"}),": More faithful report than ",(0,r.jsx)(n.code,{children:"L5"}),", when there is an infinity value. For example, array size:\n",(0,r.jsx)(n.code,{children:"[3,3]"}),", offset: ",(0,r.jsx)(n.code,{children:"[0, +oo]"}),"."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"L3"}),": The reports that are not included in the above cases."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"S2"}),": An array access is unsafe by symbolic values. For example, array size: ",(0,r.jsx)(n.code,{children:"[n,n]"}),", offset\n",(0,r.jsx)(n.code,{children:"[n,+oo]"}),"."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"U5"}),": An array access is unsafe by unknown values, which are usually from unknown function\ncalls."]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"buffer_overrun_l2",children:"BUFFER_OVERRUN_L2"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Buffer Overrun L2" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-bufferoverrun",children:"bufferoverrun"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["See ",(0,r.jsx)(n.a,{href:"#buffer_overrun_l1",children:"BUFFER_OVERRUN_L1"})]}),"\n",(0,r.jsx)(n.h2,{id:"buffer_overrun_l3",children:"BUFFER_OVERRUN_L3"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Buffer Overrun L3" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-bufferoverrun",children:"bufferoverrun"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["See ",(0,r.jsx)(n.a,{href:"#buffer_overrun_l1",children:"BUFFER_OVERRUN_L1"})]}),"\n",(0,r.jsx)(n.h2,{id:"buffer_overrun_l4",children:"BUFFER_OVERRUN_L4"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Buffer Overrun L4" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-bufferoverrun",children:"bufferoverrun"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["See ",(0,r.jsx)(n.a,{href:"#buffer_overrun_l1",children:"BUFFER_OVERRUN_L1"})]}),"\n",(0,r.jsx)(n.h2,{id:"buffer_overrun_l5",children:"BUFFER_OVERRUN_L5"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Buffer Overrun L5" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-bufferoverrun",children:"bufferoverrun"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["See ",(0,r.jsx)(n.a,{href:"#buffer_overrun_l1",children:"BUFFER_OVERRUN_L1"})]}),"\n",(0,r.jsx)(n.h2,{id:"buffer_overrun_s2",children:"BUFFER_OVERRUN_S2"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Buffer Overrun S2" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-bufferoverrun",children:"bufferoverrun"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["See ",(0,r.jsx)(n.a,{href:"#buffer_overrun_l1",children:"BUFFER_OVERRUN_L1"})]}),"\n",(0,r.jsx)(n.h2,{id:"buffer_overrun_u5",children:"BUFFER_OVERRUN_U5"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Buffer Overrun U5" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-bufferoverrun",children:"bufferoverrun"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["See ",(0,r.jsx)(n.a,{href:"#buffer_overrun_l1",children:"BUFFER_OVERRUN_L1"})]}),"\n",(0,r.jsx)(n.h2,{id:"captured_strong_self",children:"CAPTURED_STRONG_SELF"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#resource-leak",children:"Resource leak"}),'. Reported as "Captured strongSelf" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-self-in-block",children:"self-in-block"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This check is about when a strong pointer to ",(0,r.jsx)(n.code,{children:"self"})," is captured in a block.\nThis could lead to retain cycles or unexpected behavior since to avoid retain\ncycles one usually uses a local strong pointer or a captured weak pointer instead."]}),"\n",(0,r.jsx)(n.p,{children:"This will happen in one of two cases generally:"}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsxs)(n.li,{children:["One uses ",(0,r.jsx)(n.code,{children:"weakSelf"})," but forgot to declare it weak first."]}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"Example:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objectivec",children:" __typeof(self) weakSelf = self;\n int (^my_block)(BOOL) = ^(BOOL isTapped) {\n __strong __typeof(weakSelf) strongSelf = weakSelf;\n return strongSelf->x;\n };\n"})}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"Action:"})," Replace the first line with ",(0,r.jsx)(n.code,{children:"__weak __typeof(self) weakSelf = self;"}),"."]}),"\n",(0,r.jsxs)(n.ol,{start:"2",children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["One is using ",(0,r.jsx)(n.code,{children:"strongSelf"}),", declared in a block, in another inner block.\nThe retain cycle is avoided in the outer block because ",(0,r.jsx)(n.code,{children:"strongSelf"})," is a\nlocal variable of the block. If ",(0,r.jsx)(n.code,{children:"strongSelf"})," is used in the inner block,\nthen it's not a local variable anymore, but a captured variable."]}),"\n",(0,r.jsx)(n.p,{children:"Example:"}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objectivec",children:" __weak __typeof(self) weakSelf = self;\n int (^my_block)() = ^() {\n __strong typeof(self) strongSelf = weakSelf;\n if (strongSelf) {\n int (^my_block)() = ^() {\n int x = strongSelf->x;\n ...\n };\n ...\n }\n ...\n };\n"})}),"\n",(0,r.jsxs)(n.p,{children:["In this example, ",(0,r.jsx)(n.code,{children:"strongSelf"})," is a captured variable of the inner block, and this could cause retain cycles."]}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"Action:"})," Use a new pointer to self local to the inner block. In the example:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objectivec",children:" __weak __typeof(self) weakSelf = self;\n int (^my_block)() = ^() {\n __strong typeof(self) strongSelf = weakSelf;\n if (strongSelf) {\n int (^my_block)() = ^() {\n __typeof(self) innerStrongSelf = weakSelf;\n int x = innerStrongSelf->x;\n ...\n };\n ...\n }\n ...\n };\n"})}),"\n",(0,r.jsx)(n.p,{children:"Or, to improve readability, move the inner block logic into a separate method."}),"\n",(0,r.jsx)(n.p,{children:"Another solution could be to copy the instance variable that one needs to access inside the inner block to a local variable, and use the local variable instead:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objectivec",children:" __weak __typeof(self) weakSelf = self;\n int (^my_block)() = ^() {\n __strong typeof(self) strongSelf = weakSelf;\n if (strongSelf) {\n int my_x = strongSelf->x;\n int (^my_block)() = ^() {\n int x = my_x;\n ...\n };\n ...\n }\n ...\n };\n"})}),"\n",(0,r.jsx)(n.h2,{id:"checkers_allocates_memory",children:"CHECKERS_ALLOCATES_MEMORY"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#perf-regression",children:"Perf regression"}),'. Reported as "Allocates Memory" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-annotation-reachability",children:"annotation-reachability"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A method annotated with ",(0,r.jsx)(n.code,{children:"@NoAllocation"})," transitively calls ",(0,r.jsx)(n.code,{children:"new"}),"."]}),"\n",(0,r.jsx)(n.p,{children:"Example:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"class C implements I {\n @NoAllocation\n void directlyAllocatingMethod() {\n new Object();\n }\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"checkers_annotation_reachability_error",children:"CHECKERS_ANNOTATION_REACHABILITY_ERROR"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#user-defined-property",children:"User defined property"}),'. Reported as "Annotation Reachability Error" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-annotation-reachability",children:"annotation-reachability"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A method annotated with an annotation ",(0,r.jsx)(n.code,{children:"@A"})," transitively calls a method annotated ",(0,r.jsx)(n.code,{children:"@B"})," where the combination of annotations is forbidden (for example, ",(0,r.jsx)(n.code,{children:"@UiThread"})," calling ",(0,r.jsx)(n.code,{children:"@WorkerThread"}),")."]}),"\n",(0,r.jsx)(n.h2,{id:"checkers_calls_expensive_method",children:"CHECKERS_CALLS_EXPENSIVE_METHOD"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#perf-regression",children:"Perf regression"}),'. Reported as "Expensive Method Called" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-annotation-reachability",children:"annotation-reachability"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A method annotated with ",(0,r.jsx)(n.code,{children:"@PerformanceCritical"})," transitively calls a method annotated ",(0,r.jsx)(n.code,{children:"@Expensive"}),"."]}),"\n",(0,r.jsx)(n.p,{children:"Example:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"class C {\n @PerformanceCritical\n void perfCritical() {\n expensive();\n }\n\n @Expensive\n void expensive() {}\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"checkers_expensive_overrides_unannotated",children:"CHECKERS_EXPENSIVE_OVERRIDES_UNANNOTATED"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Expensive Overrides Unannotated" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-annotation-reachability",children:"annotation-reachability"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A method annotated with ",(0,r.jsx)(n.code,{children:"@Expensive"})," overrides an un-annotated method."]}),"\n",(0,r.jsx)(n.p,{children:"Example:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"interface I {\n void foo();\n}\n\nclass A implements I {\n @Expensive\n public void foo() {}\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"checkers_fragment_retains_view",children:"CHECKERS_FRAGMENT_RETAINS_VIEW"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#resource-leak",children:"Resource leak"}),'. Reported as "Fragment Retains View" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-fragment-retains-view",children:"fragment-retains-view"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This error type is Android-specific. It fires when a ",(0,r.jsx)(n.code,{children:"Fragment"})," type fails to\nnullify one or more of its declared ",(0,r.jsx)(n.code,{children:"View"})," fields in ",(0,r.jsx)(n.code,{children:"onDestroyView"}),". In\nperformance-sensitive applications, a ",(0,r.jsx)(n.code,{children:"Fragment"})," should initialize all ",(0,r.jsx)(n.code,{children:"View"}),"'s\nin ",(0,r.jsx)(n.code,{children:"onCreateView"})," and nullify them in ",(0,r.jsx)(n.code,{children:"onDestroyView"}),". If a ",(0,r.jsx)(n.code,{children:"Fragment"})," is placed\non the back stack and fails to nullify a ",(0,r.jsx)(n.code,{children:"View"})," in ",(0,r.jsx)(n.code,{children:"onDestroyView"}),", it will\nretain a useless reference to that ",(0,r.jsx)(n.code,{children:"View"})," that will not be cleaned up until the\n",(0,r.jsx)(n.code,{children:"Fragment"})," is resumed or destroyed."]}),"\n",(0,r.jsxs)(n.p,{children:["Action: Nullify the ",(0,r.jsx)(n.code,{children:"View"})," in question in ",(0,r.jsx)(n.code,{children:"onDestroyView"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"compared_to_null_and_dereferenced",children:"COMPARED_TO_NULL_AND_DEREFERENCED"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#null-pointer-dereference",children:"Null pointer dereference"}),'. Reported as "Compared To Null And Dereferenced" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"A pointer that has both been compared to null, whcich suggests that it could be null, but has also been dereferenced without a null check."}),"\n",(0,r.jsx)(n.h2,{id:"config_impact",children:"CONFIG_IMPACT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#perf-regression",children:"Perf regression"}),'. Reported as "Config Impact" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-config-impact-analysis",children:"config-impact-analysis"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["Infer reports this issue when an ",(0,r.jsx)(n.em,{children:"expensive"})," function is called without a ",(0,r.jsx)(n.em,{children:"config check"}),". The\n",(0,r.jsx)(n.em,{children:"config"})," is usually a boolean value that enables experimental new features and it is defined per\napplication/codebase, e.g. gatekeepers. To determine whether a function is expensive or not, the\nchecker relies on modeled functions that are assumed to be expensive, e.g. string operations,\nregular expression match, or DB accesses."]}),"\n",(0,r.jsxs)(n.p,{children:["Similar to ",(0,r.jsx)(n.a,{href:"/docs/next/checker-cost",children:"Cost analysis"}),", this issue type is reported only in\ndifferential mode, i.e. when there are original code and modified one and we can compare Infer's\nresults on both of them."]}),"\n",(0,r.jsx)(n.p,{children:"For instance, if we have the following code"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"// version1\nfoo();\nif (config_check){\n bar();\n}\n"})}),"\n",(0,r.jsx)(n.p,{children:"which is then modified to next"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"// version2\nfoo();\nif (config_check){\n bar();\n}\ngoo(); // added\n"})}),"\n",(0,r.jsxs)(n.p,{children:['the analysis would warn the developer that "',(0,r.jsx)(n.code,{children:"goo()"}),' is a newly added function call and it might\ncause an unexpected new behavior". However, if we were to add ',(0,r.jsx)(n.code,{children:"goo()"})," right after ",(0,r.jsx)(n.code,{children:"bar()"}),", then\nInfer wouldn't warn about it because it is already gated under the ",(0,r.jsx)(n.code,{children:"config_check"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["The analysis is inter-procedural: it can reason about impacts by code changes not only inside a\nsingle procedure, but also the impacts that are propagated by function calls. Thus, if we were to\nmodify ",(0,r.jsx)(n.code,{children:"version1"})," to ",(0,r.jsx)(n.code,{children:"version3"})," below by calling ",(0,r.jsx)(n.code,{children:"goo()"})," in ",(0,r.jsx)(n.code,{children:"foo()"}),","]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"// version3\nvoid foo(){\n // ....\n goo(); // added\n}\n"})}),"\n",(0,r.jsxs)(n.p,{children:["then the analysis will report a ",(0,r.jsx)(n.code,{children:"CONFIG_IMPACT"})," issue on the ungated call site of ",(0,r.jsx)(n.code,{children:"foo()"}),"."]}),"\n",(0,r.jsx)(n.p,{children:"Currently, the analysis supports both Objective-C and Java but not C++."}),"\n",(0,r.jsx)(n.p,{children:"Action: Make sure the ungated code change is semantically correct and harmless in terms of execution\ncost. If you are not sure, gate it with a new or pre-existing config."}),"\n",(0,r.jsx)(n.h2,{id:"config_impact_strict",children:"CONFIG_IMPACT_STRICT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#ungated-code",children:"Ungated code"}),'. Reported as "Config Impact Strict" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-config-impact-analysis",children:"config-impact-analysis"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This is similar to ",(0,r.jsxs)(n.a,{href:"#config_impact",children:[(0,r.jsx)(n.code,{children:"CONFIG_IMPACT"})," issue"]})," but the analysis reports ",(0,r.jsx)(n.strong,{children:"all"})," ungated\ncodes irrespective of whether they are expensive or not."]}),"\n",(0,r.jsx)(n.h2,{id:"config_usage",children:"CONFIG_USAGE"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Config Usage" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["Infer reports this issue when a ",(0,r.jsx)(n.em,{children:"config"})," value is used as branch condition in a function. The\n",(0,r.jsx)(n.em,{children:"config"})," is usually a boolean value that enables experimental new features and it is defined per\napplication/codebase, e.g. gatekeepers."]}),"\n",(0,r.jsx)(n.p,{children:"For instance, if we have the following code"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-cpp",children:'void foo() {\n if(config_check("my_new_feature")){ ... }\n}\n'})}),"\n",(0,r.jsxs)(n.p,{children:['then analysis would provide information that "the function ',(0,r.jsx)(n.code,{children:"foo"})," uses the config ",(0,r.jsx)(n.code,{children:"my_new_feature"}),' as\nbranch condition".']}),"\n",(0,r.jsx)(n.p,{children:"Note: This type of issue is only for providing semantic information, rather than warning or\nreporting actual problem."}),"\n",(0,r.jsx)(n.h2,{id:"constant_address_dereference",children:"CONSTANT_ADDRESS_DEREFERENCE"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Constant Address Dereference" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This is reported when an address at an absolute location, e.g. 1234,\nis dereferenced. It is a more general version of the\n",(0,r.jsx)(n.a,{href:"#nullptr_dereference",children:(0,r.jsx)(n.code,{children:"NULLPTR_DEREFERENCE"})})," error type that is\nreported when the address is a constant other than zero."]}),"\n",(0,r.jsxs)(n.p,{children:["For example, ",(0,r.jsx)(n.code,{children:"int *p = (int *) 123; *p = 42;"})," generates a ",(0,r.jsx)(n.code,{children:"CONSTANT_ADDRESS_DEREFERENCE"})," on ",(0,r.jsx)(n.code,{children:"*p = 42;"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["For more information see the ",(0,r.jsx)(n.a,{href:"#nullptr_dereference",children:(0,r.jsx)(n.code,{children:"NULLPTR_DEREFERENCE"})})," issue type."]}),"\n",(0,r.jsx)(n.h2,{id:"constant_address_dereference_latent",children:"CONSTANT_ADDRESS_DEREFERENCE_LATENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Constant Address Dereference Latent" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A latent ",(0,r.jsx)(n.a,{href:"#constant_address_dereference",children:"CONSTANT_ADDRESS_DEREFERENCE"}),". See the ",(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse#latent-issues",children:"documentation on Pulse latent issues"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"cxx_ref_captured_in_block",children:"CXX_REF_CAPTURED_IN_BLOCK"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#memory-error",children:"Memory error"}),'. Reported as "C++ Reference Captured in Block" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-self-in-block",children:"self-in-block"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This check flags when a C++ reference is captured in an escaping block.\nThis means that the block will be leaving the current scope, i.e. it is\nnot annotated with ",(0,r.jsx)(n.code,{children:"__attribute__((noescape))"}),"."]}),"\n",(0,r.jsx)(n.p,{children:"Example:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"- (void)ref_captured_in_escaping_block_bad:(int&)y {\n dispatch_async(dispatch_get_main_queue(), ^{\n int a = y;\n ...\n });\n ...;\n}\n"})}),"\n",(0,r.jsx)(n.p,{children:"This could cause crashes because C++ references are not managed pointers\n(like ARC pointers) and so the referent is likely to be gone if the block\ndereferences it later."}),"\n",(0,r.jsx)(n.h2,{id:"cxx_string_captured_in_block",children:"CXX_STRING_CAPTURED_IN_BLOCK"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#memory-error",children:"Memory error"}),'. Reported as "C++ String Captured in Block" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-self-in-block",children:"self-in-block"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This check flags when an internal pointer of a local variable of type ",(0,r.jsx)(n.code,{children:"std::string"})," is captured in an escaping block.\nThis means that the block will be leaving the current scope, i.e. it is\nnot annotated with ",(0,r.jsx)(n.code,{children:"__attribute__((noescape))"}),"."]}),"\n",(0,r.jsx)(n.p,{children:"Example:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:" std::string fullName;\n const char* c = fullName.c_str();\n dispatch_async(dispatch_get_main_queue(), ^{\n const char* c1 = c;\n });\n"})}),"\n",(0,r.jsx)(n.p,{children:"This could cause crashes because the variable is likely to be freed when the code is executed, leaving the pointer dangling."}),"\n",(0,r.jsx)(n.h2,{id:"dangling_pointer_dereference",children:"DANGLING_POINTER_DEREFERENCE"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Dangling Pointer Dereference" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-biabduction",children:"biabduction"}),"."]})}),"\n",(0,r.jsx)(n.h2,{id:"data_flow_to_sink",children:"DATA_FLOW_TO_SINK"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#sensitive-data-flow",children:"Sensitive data flow"}),'. Reported as "Data Flow to Sink" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"A flow of data was detected to a sink."}),"\n",(0,r.jsx)(n.h2,{id:"deadlock",children:"DEADLOCK"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#concurrency",children:"Concurrency"}),'. Reported as "Deadlock" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-starvation",children:"starvation"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"This error is currently reported in Java. A deadlock occurs when two distinct\nthreads try to acquire two locks in reverse orders. The following code\nillustrates a textbook example. Of course, in real deadlocks, the lock\nacquisitions may be separated by deeply nested call chains."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:" public void lockAThenB() {\n synchronized(lockA) {\n synchronized(lockB) {\n // do something with both resources\n }\n }\n }\n\n public void lockBThenA() {\n synchronized(lockB) {\n synchronized(lockA) {\n // do something with both resources\n }\n }\n }\n"})}),"\n",(0,r.jsx)(n.p,{children:"The standard solution to a deadlock is to fix an order of lock acquisition and\nadhere to that order in all cases. Another solution may be to shrink the\ncritical sections (i.e., the code executing under lock) to the minimum required."}),"\n",(0,r.jsxs)(n.p,{children:["Old-style containers such as ",(0,r.jsx)(n.code,{children:"Vector"})," are synchronized on the object monitor,\nwhich means that deadlocks can occur even without explicit synchronisation on\nboth threads. For instance:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:" public void lockAThenAddToVector() {\n synchronized(lockA) {\n vector.add(object);\n }\n }\n\n public void lockVectorThenA() {\n synchronized(vector) {\n synchronized(lockA) {\n // do something with both resources\n }\n }\n }\n"})}),"\n",(0,r.jsx)(n.p,{children:"Infer has support for detecting these deadlocks too."}),"\n",(0,r.jsxs)(n.p,{children:["To suppress reports of deadlocks in a method ",(0,r.jsx)(n.code,{children:"m()"})," use the\n",(0,r.jsx)(n.code,{children:'@SuppressLint("DEADLOCK")'})," annotation, as follows:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:' import android.annotation.SuppressLint;\n\n @SuppressLint("DEADLOCK")\n public void m() {\n ...\n }\n'})}),"\n",(0,r.jsx)(n.h2,{id:"dead_store",children:"DEAD_STORE"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#logic-error",children:"Logic error"}),'. Reported as "Dead Store" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-liveness",children:"liveness"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This error is reported in C++. It fires when the value assigned to a variables\nis never used (e.g., ",(0,r.jsx)(n.code,{children:"int i = 1; i = 2; return i;"}),")."]}),"\n",(0,r.jsx)(n.h2,{id:"divide_by_zero",children:"DIVIDE_BY_ZERO"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Divide By Zero" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-biabduction",children:"biabduction"}),"."]})}),"\n",(0,r.jsx)(n.h2,{id:"empty_vector_access",children:"EMPTY_VECTOR_ACCESS"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Empty Vector Access" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-biabduction",children:"biabduction"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"This error type is reported only in C++, in versions >= C++11."}),"\n",(0,r.jsx)(n.p,{children:"The code is trying to access an element of a vector that Infer believes to be\nempty. Such an access will cause undefined behavior at runtime."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-cpp",children:"#include \nint foo(){\n const std::vector vec;\n return vec[0]; // Empty vector access reported here\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"execution_time_complexity_increase",children:"EXECUTION_TIME_COMPLEXITY_INCREASE"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Execution Time Complexity Increase" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-cost",children:"cost"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["Infer reports this issue when the execution time complexity of a\nprogram increases in degree: e.g. from constant to linear or from\nlogarithmic to quadratic. This issue type is only reported in\ndifferential mode: i.e when we are comparing the cost analysis results of\ntwo runs of infer on a file. Check out examples in ",(0,r.jsx)(n.a,{href:"/docs/next/checker-cost#examples-execution-cost",children:"here"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"execution_time_complexity_increase_ui_thread",children:"EXECUTION_TIME_COMPLEXITY_INCREASE_UI_THREAD"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Execution Time Complexity Increase Ui Thread" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-cost",children:"cost"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["Infer reports this issue when the execution time complexity of the procedure increases in degree ",(0,r.jsx)(n.strong,{children:"and"})," the procedure runs on the UI (main) thread."]}),"\n",(0,r.jsx)(n.p,{children:"Infer considers a method as running on the UI thread whenever:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["The method, one of its overrides, its class, or an ancestral class, is\nannotated with ",(0,r.jsx)(n.code,{children:"@UiThread"}),"."]}),"\n",(0,r.jsxs)(n.li,{children:["The method, or one of its overrides is annotated with ",(0,r.jsx)(n.code,{children:"@OnEvent"}),", ",(0,r.jsx)(n.code,{children:"@OnClick"}),",\netc."]}),"\n",(0,r.jsxs)(n.li,{children:["The method or its callees call a ",(0,r.jsx)(n.code,{children:"Litho.ThreadUtils"})," method such as\n",(0,r.jsx)(n.code,{children:"assertMainThread"}),"."]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"execution_time_unreachable_at_exit",children:"EXECUTION_TIME_UNREACHABLE_AT_EXIT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Execution Time Unreachable At Exit" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-cost",children:"cost"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"This issue type indicates that the program's execution doesn't reach\nthe exit node (where our analysis computes the final cost of the\nprocedure). Hence, we cannot compute a static bound for the procedure."}),"\n",(0,r.jsx)(n.p,{children:"Examples:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"void exit_unreachable() {\n exit(0); // modeled as unreachable\n}\n\nvoid infeasible_path_unreachable() {\n Preconditions.checkState(false); // like assert false, state pruned to bottom\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"expensive_execution_time",children:"EXPENSIVE_EXECUTION_TIME"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Expensive Execution Time" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-cost",children:"cost"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["[EXPERIMENTAL] This warning indicates that the procedure has non-constant and non-top execution cost. By default, this issue type is disabled. To enable it, set ",(0,r.jsx)(n.code,{children:"enabled=true"})," in ",(0,r.jsx)(n.a,{href:"https://github.com/facebook/infer/blob/main/infer/src/base/costKind.ml#L55",children:"costKind.ml"}),"."]}),"\n",(0,r.jsx)(n.p,{children:"For instance, a simple example where we report this issue is a function with linear cost:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"int sum_linear(ArrayList list){\n int sum = 0;\n for (Integer el: list){\n sum += el;\n }\n return sum;\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"expensive_loop_invariant_call",children:"EXPENSIVE_LOOP_INVARIANT_CALL"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Expensive Loop Invariant Call" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-loop-hoisting",children:"loop-hoisting"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["We report this issue type when a function is ",(0,r.jsx)(n.a,{href:"/docs/next/all-issue-types#invariant_call",children:"loop-invariant"})," and also expensive (i.e. at least has linear complexity as determined by the ",(0,r.jsx)(n.a,{href:"/docs/next/checker-cost",children:"cost"})," analysis)."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"int incr(int x) {\n return x + 1;\n}\n\n// incr will not be hoisted since it is cheap(constant time)\nvoid foo_linear(int size) {\n int x = 10;\n for (int i = 0; i < size; i++) {\n incr(x); // constant call, don't hoist\n }\n}\n\n// call to foo_linear will be hoisted since it is expensive(linear in size).\nvoid symbolic_expensive_hoist(int size) {\n for (int i = 0; i < size; i++) {\n foo_linear(size); // hoist\n }\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"guardedby_violation",children:"GUARDEDBY_VIOLATION"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#concurrency",children:"Concurrency"}),'. Reported as "GuardedBy Violation" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-racerd",children:"racerd"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A field annotated with ",(0,r.jsx)(n.code,{children:"@GuardedBy"})," is being accessed by a call-chain that starts at a non-private method without synchronization."]}),"\n",(0,r.jsx)(n.p,{children:"Example:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:'class C {\n @GuardedBy("this")\n String f;\n\n void foo(String s) {\n f = s; // unprotected access here\n }\n}\n'})}),"\n",(0,r.jsxs)(n.p,{children:["Action: Protect the offending access by acquiring the lock indicated by the ",(0,r.jsx)(n.code,{children:"@GuardedBy(...)"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"impure_function",children:"IMPURE_FUNCTION"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Impure Function" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-impurity",children:"impurity"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"This issue type indicates impure functions. For instance, below functions would be marked as impure:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"void makeAllZero_impure(ArrayList list) {\n Iterator listIterator = list.iterator();\n while (listIterator.hasNext()) {\n Foo foo = listIterator.next();\n foo.x = 0;\n }\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"inefficient_keyset_iterator",children:"INEFFICIENT_KEYSET_ITERATOR"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#perf-regression",children:"Perf regression"}),'. Reported as "Inefficient Keyset Iterator" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-inefficient-keyset-iterator",children:"inefficient-keyset-iterator"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"This issue is raised when"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["iterating over a HashMap with ",(0,r.jsx)(n.code,{children:"keySet()"})," iterator"]}),"\n",(0,r.jsx)(n.li,{children:"looking up the key each time"}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"Example:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"void inefficient_loop_bad(HashMap testMap) {\n for (String key : testMap.keySet()) {\n Integer value = testMap.get(key); // extra look-up cost\n foo(key, value);\n }\n}\n"})}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"Action"}),":"]}),"\n",(0,r.jsxs)(n.p,{children:["Instead, it is more efficient to iterate over the loop with ",(0,r.jsx)(n.code,{children:"entrySet"})," which returns key-vaue pairs and gets rid of the hashMap lookup."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"void efficient_loop_ok(HashMap testMap) {\n for (Map.Entry entry : testMap.entrySet()) {\n String key = entry.getKey();\n Integer value = entry.getValue();\n foo(key, value);\n }\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"inferbo_alloc_is_big",children:"INFERBO_ALLOC_IS_BIG"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Alloc Is Big" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-bufferoverrun",children:"bufferoverrun"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"malloc"})," is passed a large constant value (>=10^6). For example, ",(0,r.jsx)(n.code,{children:"int n = 1000000; malloc(n);"})," generates ",(0,r.jsx)(n.code,{children:"INFERBO_ALLOC_IS_BIG"})," on ",(0,r.jsx)(n.code,{children:"malloc(n)"}),"."]}),"\n",(0,r.jsx)(n.p,{children:"Action: Fix the size argument or make sure it is really needed."}),"\n",(0,r.jsx)(n.h2,{id:"inferbo_alloc_is_negative",children:"INFERBO_ALLOC_IS_NEGATIVE"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Alloc Is Negative" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-bufferoverrun",children:"bufferoverrun"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"malloc"})," is called with a negative size. For example, ",(0,r.jsx)(n.code,{children:"int n = 3 - 5; malloc(n);"})," generates ",(0,r.jsx)(n.code,{children:"INFERBO_ALLOC_IS_NEGATIVE"})," on ",(0,r.jsx)(n.code,{children:"malloc(n)"}),"."]}),"\n",(0,r.jsx)(n.p,{children:"Action: Fix the size argument."}),"\n",(0,r.jsx)(n.h2,{id:"inferbo_alloc_is_zero",children:"INFERBO_ALLOC_IS_ZERO"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Alloc Is Zero" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-bufferoverrun",children:"bufferoverrun"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"malloc"})," is called with a zero size. For example, ",(0,r.jsx)(n.code,{children:"int n = 3 - 3; malloc(n);"})," generates ",(0,r.jsx)(n.code,{children:"INFERBO_ALLOC_IS_ZERO"})," on ",(0,r.jsx)(n.code,{children:"malloc(n)"}),"."]}),"\n",(0,r.jsx)(n.p,{children:"Action: Fix the size argument."}),"\n",(0,r.jsx)(n.h2,{id:"inferbo_alloc_may_be_big",children:"INFERBO_ALLOC_MAY_BE_BIG"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Alloc May Be Big" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-bufferoverrun",children:"bufferoverrun"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"malloc"})," ",(0,r.jsx)(n.em,{children:"may"})," be called with a large value. For example, ",(0,r.jsx)(n.code,{children:"int n = b ? 3 : 1000000; malloc(n);"})," generates ",(0,r.jsx)(n.code,{children:"INFERBO_ALLOC_MAY_BE_BIG"})," on ",(0,r.jsx)(n.code,{children:"malloc(n)"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["Action: Fix the size argument or add a bound checking, e.g. ",(0,r.jsx)(n.code,{children:"if (n < A_SMALL_NUMBER) { malloc(n); }"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"inferbo_alloc_may_be_negative",children:"INFERBO_ALLOC_MAY_BE_NEGATIVE"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Alloc May Be Negative" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-bufferoverrun",children:"bufferoverrun"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"malloc"})," ",(0,r.jsx)(n.em,{children:"may"})," be called with a negative value. For example, ",(0,r.jsx)(n.code,{children:"int n = b ? 3 : -5; malloc(n);"})," generates ",(0,r.jsx)(n.code,{children:"INFERBO_ALLOC_MAY_BE_NEGATIVE"})," on ",(0,r.jsx)(n.code,{children:"malloc(n)"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["Action: Fix the size argument or add a bound checking, e.g. ",(0,r.jsx)(n.code,{children:"if (n > 0) { malloc(n); }"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"infinite_execution_time",children:"INFINITE_EXECUTION_TIME"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Infinite Execution Time" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-cost",children:"cost"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"This warning indicates that Infer was not able to determine a static\nupper bound on the execution cost of the procedure. By default, this\nissue type is disabled."}),"\n",(0,r.jsx)(n.h3,{id:"example-1-t-due-to-expressivity",children:"Example 1: T due to expressivity"}),"\n",(0,r.jsx)(n.p,{children:"For instance, Inferbo's interval analysis is limited to affine\nexpressions. Hence, we can't statically estimate an upper bound on the\nbelow example and obtain T(unknown) cost:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"// Expected: square root(x), got T\nvoid square_root_FP(int x) {\n int i = 0;\n while (i * i < x) {\n i++;\n }\n}\n"})}),"\n",(0,r.jsx)(n.h3,{id:"example-2-t-due-to-unmodeled-calls",children:"Example 2: T due to unmodeled calls"}),"\n",(0,r.jsx)(n.p,{children:"Another common case where we get T cost is when Infer cannot statically determine the range of values for loop bounds. For instance,"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"void loop_over_charArray_FP(StringBuilder builder, String input) {\n for (Character c : input.toCharArray()) {}\n}\n"})}),"\n",(0,r.jsxs)(n.p,{children:["Here, Infer does not have any InferBo models for the range of values returned by ",(0,r.jsx)(n.code,{children:"String.toCharArray"}),", hence it cannot determine that we will be iterating over a char array in the size of ",(0,r.jsx)(n.code,{children:"input"})," string."]}),"\n",(0,r.jsxs)(n.p,{children:["To teach InferBo about such library calls, they should be semantically modeled in ",(0,r.jsx)(n.a,{href:"https://github.com/facebook/infer/blob/main/infer/src/bufferoverrun/bufferOverrunModels.ml",children:"InferBo"}),"."]}),"\n",(0,r.jsx)(n.h3,{id:"example-3-t-due-to-calling-another-t-costed-function",children:"Example 3: T due to calling another T-costed function"}),"\n",(0,r.jsx)(n.p,{children:"Since the analysis is inter-procedural, another example we can have T cost is if at least one of the callees has T cost."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"// Expected: constant, got T\nvoid call_top_cost_FP() {\n square_root_FP(1); // square_root_FP has Top cost\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"integer_overflow_l1",children:"INTEGER_OVERFLOW_L1"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Integer Overflow L1" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-bufferoverrun",children:"bufferoverrun"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This is reported when integer overflow occurred by integer operations such as addition, subtraction,\nand multiplication. For example, ",(0,r.jsx)(n.code,{children:"int n = INT_MAX; int m = n + 3;"})," generates a INTEGER_OVERFLOW_L1\non ",(0,r.jsx)(n.code,{children:"n + 3"}),"."]}),"\n",(0,r.jsx)(n.p,{children:'Integer overflows reports fall into several "buckets" corresponding to the expected precision of the\nreport. The higher the number, the more likely it is to be a false positive.'}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"L1"}),": The most faithful report, when it ",(0,r.jsx)(n.em,{children:"must"})," be unsafe. For example,\n",(0,r.jsx)(n.code,{children:"[2147483647,2147483647] + [1,1]"})," in 32-bit signed integer type."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"L2"}),": Less faithful report than ",(0,r.jsx)(n.code,{children:"L1"}),", when it ",(0,r.jsx)(n.em,{children:"may"})," be unsafe. For example,\n",(0,r.jsx)(n.code,{children:"[2147483647,2147483647] + [0,1]"})," in 32-bit signed integer type. Note that the integer of RHS\ncan be 0, which is safe."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"L5"}),": The reports that are not included in the above cases."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"U5"}),": A binary integer operation is unsafe by unknown values, which are usually from unknown\nfunction calls."]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"integer_overflow_l2",children:"INTEGER_OVERFLOW_L2"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Integer Overflow L2" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-bufferoverrun",children:"bufferoverrun"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["See ",(0,r.jsx)(n.a,{href:"#integer_overflow_l1",children:"INTEGER_OVERFLOW_L1"})]}),"\n",(0,r.jsx)(n.h2,{id:"integer_overflow_l5",children:"INTEGER_OVERFLOW_L5"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Integer Overflow L5" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-bufferoverrun",children:"bufferoverrun"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["See ",(0,r.jsx)(n.a,{href:"#integer_overflow_l1",children:"INTEGER_OVERFLOW_L1"})]}),"\n",(0,r.jsx)(n.h2,{id:"integer_overflow_u5",children:"INTEGER_OVERFLOW_U5"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Integer Overflow U5" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-bufferoverrun",children:"bufferoverrun"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["See ",(0,r.jsx)(n.a,{href:"#integer_overflow_l1",children:"INTEGER_OVERFLOW_L1"})]}),"\n",(0,r.jsx)(n.h2,{id:"interface_not_thread_safe",children:"INTERFACE_NOT_THREAD_SAFE"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#concurrency",children:"Concurrency"}),'. Reported as "Interface Not Thread Safe" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-racerd",children:"racerd"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This error indicates that you have invoked an interface method not annotated\nwith ",(0,r.jsx)(n.code,{children:"@ThreadSafe"})," from a thread-safe context (e.g., code that uses locks or is\nmarked ",(0,r.jsx)(n.code,{children:"@ThreadSafe"}),"). The fix is to add the ",(0,r.jsx)(n.code,{children:"@ThreadSafe"})," annotation to the\ninterface or to the interface method. For background on why these annotations\nare needed, see the detailed explanation\n",(0,r.jsx)(n.a,{href:"/docs/next/checker-racerd#interface-not-thread-safe",children:"here"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"invalid_sil",children:"INVALID_SIL"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Invalid Sil" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-sil-validation",children:"sil-validation"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"The SIL instruction does not conform to the expected subset of instructions\nexpected for the front-end of the language for the analyzed code."}),"\n",(0,r.jsx)(n.h2,{id:"invariant_call",children:"INVARIANT_CALL"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Invariant Call" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-loop-hoisting",children:"loop-hoisting"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"We report this issue type when a function call is loop-invariant and hoistable, i.e."}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"the function has no side side effects (pure)"}),"\n",(0,r.jsx)(n.li,{children:"has invariant arguments and result (i.e. have the same value in all loop iterations)"}),"\n",(0,r.jsx)(n.li,{children:"it is guaranteed to execute, i.e. it dominates all loop sources"}),"\n"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"int foo(int x, int y) {\n return x + y;\n}\n\n\nvoid invariant_hoist(int size) {\n int x = 10;\n int y = 5;\n for (int i = 0; i < size; i++) {\n foo(x, y); // hoistable\n }\n }\n"})}),"\n",(0,r.jsx)(n.h2,{id:"ipc_on_ui_thread",children:"IPC_ON_UI_THREAD"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#perf-regression",children:"Perf regression"}),'. Reported as "Ipc On Ui Thread" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-starvation",children:"starvation"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A blocking ",(0,r.jsx)(n.code,{children:"Binder"})," IPC call occurs on the UI thread."]}),"\n",(0,r.jsx)(n.h2,{id:"lab_resource_leak",children:"LAB_RESOURCE_LEAK"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Lab Resource Leak" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-resource-leak-lab",children:"resource-leak-lab"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"Toy issue."}),"\n",(0,r.jsx)(n.h2,{id:"lineage_flow",children:"LINEAGE_FLOW"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#sensitive-data-flow",children:"Sensitive data flow"}),'. Reported as "Lineage Flow" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-lineage",children:"lineage"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"A Lineage taint flow has been detected from a source to a sink."}),"\n",(0,r.jsx)(n.h2,{id:"lockless_violation",children:"LOCKLESS_VIOLATION"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Lockless Violation" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-starvation",children:"starvation"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A method implements an interface signature annotated with ",(0,r.jsx)(n.code,{children:"@Lockless"})," but which transitively acquires a lock."]}),"\n",(0,r.jsx)(n.p,{children:"Example:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"Interface I {\n @Lockless\n public void no_lock();\n}\n\nclass C implements I {\n private synchronized do_lock() {}\n\n public void no_lock() { // this method should not acquire any locks\n do_lock();\n }\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"lock_consistency_violation",children:"LOCK_CONSISTENCY_VIOLATION"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#concurrency",children:"Concurrency"}),'. Reported as "Lock Consistency Violation" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-racerd",children:"racerd"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"This is an error reported on C++ and Objective C classes whenever:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Some class method directly uses locking primitives (not transitively)."}),"\n",(0,r.jsxs)(n.li,{children:["It has a public method which writes to some member ",(0,r.jsx)(n.code,{children:"x"})," while holding a lock."]}),"\n",(0,r.jsxs)(n.li,{children:["It has a public method which reads ",(0,r.jsx)(n.code,{children:"x"})," without holding a lock."]}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:["The above may happen through a chain of calls. Above, ",(0,r.jsx)(n.code,{children:"x"})," may also be a\ncontainer (an array, a vector, etc)."]}),"\n",(0,r.jsx)(n.h3,{id:"fixing-lock-consistency-violation-reports",children:"Fixing Lock Consistency Violation reports"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Avoid the offending access (most often the read). Of course, this may not be\npossible."}),"\n",(0,r.jsx)(n.li,{children:"Use synchronization to protect the read, by using the same lock protecting the\ncorresponding write."}),"\n",(0,r.jsx)(n.li,{children:"Make the method doing the read access private. This should silence the\nwarning, since Infer looks for a pair of non-private methods. Objective-C:\nInfer considers a method as private if it's not exported in the header-file\ninterface."}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"memory_leak_c",children:"MEMORY_LEAK_C"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#resource-leak",children:"Resource leak"}),'. Reported as "Memory Leak" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsx)(n.h3,{id:"memory-leak-in-c",children:"Memory leak in C"}),"\n",(0,r.jsx)(n.p,{children:"This error type is only reported in C and Objective-C code. In Java we do not\nreport memory leaks because it is a garbage collected language."}),"\n",(0,r.jsxs)(n.p,{children:["In C, Infer reports memory leaks when objects are created with ",(0,r.jsx)(n.code,{children:"malloc"})," and not\nfreed. For example:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-c",children:"-(void) memory_leak_bug {\n struct Person *p = malloc(sizeof(struct Person));\n}\n"})}),"\n",(0,r.jsx)(n.h3,{id:"memory-leak-in-objective-c",children:"Memory leak in Objective-C"}),"\n",(0,r.jsx)(n.p,{children:"Additionally, in Objective-C, Infer reports memory leaks that happen when\nobjects from Core Foundation or Core Graphics don't get released."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objectivec",children:"-(void) memory_leak_bug_cf {\n CGPathRef shadowPath = CGPathCreateWithRect(self.inputView.bounds, NULL); //object created and not released.\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"memory_leak_cpp",children:"MEMORY_LEAK_CPP"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#resource-leak",children:"Resource leak"}),'. Reported as "Memory Leak" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["See ",(0,r.jsx)(n.a,{href:"#memory_leak_c",children:"MEMORY_LEAK_C"})]}),"\n",(0,r.jsx)(n.h2,{id:"missing_required_prop",children:"MISSING_REQUIRED_PROP"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "Missing Required Prop" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-litho-required-props",children:"litho-required-props"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This issues is reported when a required ",(0,r.jsx)(n.code,{children:"@Prop"})," is missing."]}),"\n",(0,r.jsx)(n.h2,{id:"examples",children:"Examples"}),"\n",(0,r.jsxs)(n.p,{children:["Assume that the following Litho Component specification is defined as follows where ",(0,r.jsx)(n.code,{children:"prop1"})," is optional and ",(0,r.jsx)(n.code,{children:"prop2"})," is required."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"class MyComponentSpec {\n\n static void onCreate(\n ComponentContext c,\n @Prop(optional = true) String prop1, @Prop int prop2) {\n ...\n }\n ...\n}\n"})}),"\n",(0,r.jsxs)(n.p,{children:["When we build the corresponding component, we should have all the required props. If we are missing optional props (e..g ",(0,r.jsx)(n.code,{children:"prop1"})," below), it is ok."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"MyComponent.create(c)\n .prop2(8)\n .build();\n"})}),"\n",(0,r.jsxs)(n.p,{children:["However, if we are missing a required prop, Infer gives an error below for the missing ",(0,r.jsx)(n.code,{children:"prop2"}),"."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:'MyComponent.create(c)\n .prop1("My prop 1")\n .build();\n'})}),"\n",(0,r.jsx)(n.p,{children:"** Action **"}),"\n",(0,r.jsx)(n.p,{children:"There are two ways to fix this issue."}),"\n",(0,r.jsxs)(n.p,{children:["First, we could add the missing ",(0,r.jsx)(n.code,{children:"prop2"}),":"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:'MyComponent.create(c)\n .prop1("My prop 1")\n .prop2(x) // where x is some integer\n .build();\n'})}),"\n",(0,r.jsxs)(n.p,{children:["or alternatively, if the ",(0,r.jsx)(n.code,{children:"prop2"})," is not really required, we could change the component spec to reflect that:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"class MyComponentSpec {\n\n static void onCreate(\n ComponentContext c,\n @Prop(optional = true) String prop1, @Prop(optional = true) int prop2) {\n ...\n }\n ...\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"mixed_self_weakself",children:"MIXED_SELF_WEAKSELF"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#resource-leak",children:"Resource leak"}),'. Reported as "Mixed Self WeakSelf" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-self-in-block",children:"self-in-block"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This check reports an issue when an Objective-C block captures both ",(0,r.jsx)(n.code,{children:"self"})," and ",(0,r.jsx)(n.code,{children:"weakSelf"}),", a weak pointer to ",(0,r.jsx)(n.code,{children:"self"}),".\nPossibly the developer meant to capture only ",(0,r.jsx)(n.code,{children:"weakSelf"})," to avoid a retain cycle, but made a typo and used ",(0,r.jsx)(n.code,{children:"self"}),"\ninstead of ",(0,r.jsx)(n.code,{children:"strongSelf"}),". In this case, this could cause a retain cycle."]}),"\n",(0,r.jsx)(n.p,{children:"Example:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objectivec",children:" __weak __typeof(self) weakSelf = self;\n int (^my_block)() = ^() {\n __strong __typeof(weakSelf) strongSelf = weakSelf;\n if (strongSelf) {\n [strongSelf foo];\n int x = self->x; // typo here\n }\n return 0;\n };\n"})}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"Action"}),": Fixing the typo is generally the right course of action."]}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.em,{children:"Limitations:"})," To keep this check simple and intra-procedural, we rely on names to find ",(0,r.jsx)(n.code,{children:"weakSelf"}),':\nwe assume that any captured weak pointer whose name contains "self" is a weak reference to ',(0,r.jsx)(n.code,{children:"self"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"modifies_immutable",children:"MODIFIES_IMMUTABLE"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Modifies Immutable" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-impurity",children:"impurity"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This issue type indicates modifications to fields marked as @Immutable. For instance, below function ",(0,r.jsx)(n.code,{children:"mutateArray"})," would be marked as modifying immutable field ",(0,r.jsx)(n.code,{children:"testArray"}),":"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:" @Immutable int[] testArray = new int[]{0, 1, 2, 4};\n \n int[] getTestArray() {\n return testArray;\n } \n \n void mutateArray() {\n int[] array = getTestArray();\n array[2] = 7;\n }\n"})}),"\n",(0,r.jsx)(n.h2,{id:"multiple_weakself",children:"MULTIPLE_WEAKSELF"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Multiple WeakSelf Use" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-self-in-block",children:"self-in-block"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This check reports when an Objective-C block uses ",(0,r.jsx)(n.code,{children:"weakSelf"})," (a weak pointer to ",(0,r.jsx)(n.code,{children:"self"}),") more than once.\nThis could lead to unexpected behaviour. Even if ",(0,r.jsx)(n.code,{children:"weakSelf"})," is not nil in the first use, it could be nil\nin the following uses since the object that ",(0,r.jsx)(n.code,{children:"weakSelf"})," points to could be freed anytime."]}),"\n",(0,r.jsx)(n.p,{children:"Example:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objectivec",children:" __weak __typeof(self) weakSelf = self;\n int (^my_block)() = ^() {\n [weakSelf foo];\n int x = weakSelf->x;\n };\n"})}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"Action:"}),"\nOne should assign ",(0,r.jsx)(n.code,{children:"weakSelf"})," to a strong pointer first, and then\nuse it in the block."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objectivec",children:" __weak __typeof(self) weakSelf = self;\n int (^my_block)() = ^() {\n __strong __typeof(weakSelf) strongSelf = weakSelf;\n if (strongSelf) {\n [strongSelf foo];\n int x = strongSelf->x;\n }\n ...\n };\n"})}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.em,{children:"Limitations:"})," To keep this check simple and intra-procedural, we rely on names to find ",(0,r.jsx)(n.code,{children:"weakSelf"}),':\nwe assume that any captured weak pointer whose name contains "self" is a weak reference to ',(0,r.jsx)(n.code,{children:"self"}),".\nIn contrast, ",(0,r.jsx)(n.code,{children:"strongSelf"})," is a local variable to the block, so the check supports any name given to\na local strong pointer that has been assigned ",(0,r.jsx)(n.code,{children:"weakSelf"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"mutual_recursion_cycle",children:"MUTUAL_RECURSION_CYCLE"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "Mutual Recursion Cycle" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A recursive call or mutually recursive call has been detected. This does ",(0,r.jsx)(n.em,{children:"not"})," mean that the program won't terminate, just that the code is recursive. You should double-check if the recursion is intended and if it can lead to non-termination or a stack overflow."]}),"\n",(0,r.jsx)(n.p,{children:"Example of recursive function:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-C",children:"int factorial(int x) {\n if (x > 0) {\n return x * factorial(x-1);\n } else {\n return 1;\n }\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"nil_block_call",children:"NIL_BLOCK_CALL"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#null-pointer-dereference",children:"Null pointer dereference"}),'. Reported as "Nil Block Call" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This check reports when one tries to call an Objective-C block that is ",(0,r.jsx)(n.code,{children:"nil"}),".\nThis causes a crash."]}),"\n",(0,r.jsx)(n.p,{children:"Example:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objectivec",children:"-(void) foo:(void (^)())callback {\n callback();\n}\n\n-(void) bar {\n [self foo:nil]; //crash\n}\n"})}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"Action"}),":"]}),"\n",(0,r.jsxs)(n.p,{children:["Adding a check for ",(0,r.jsx)(n.code,{children:"nil"})," before calling the block, or making sure never to call the method ",(0,r.jsx)(n.code,{children:"foo:"})," with ",(0,r.jsx)(n.code,{children:"nil"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"nil_block_call_latent",children:"NIL_BLOCK_CALL_LATENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#null-pointer-dereference",children:"Null pointer dereference"}),'. Reported as "Nil Block Call Latent" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A latent ",(0,r.jsx)(n.a,{href:"#nil_block_call",children:"NIL_BLOCK_CALL"}),". See the ",(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse#latent-issues",children:"documentation on Pulse latent issues"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"nil_insertion_into_collection",children:"NIL_INSERTION_INTO_COLLECTION"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "Nil Insertion Into Collection" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This checks reports when ",(0,r.jsx)(n.code,{children:"nil"})," is passed to collections in Objective-C such as arrays and dictionaries. This causes a crash."]}),"\n",(0,r.jsx)(n.h3,{id:"arrays",children:"Arrays"}),"\n",(0,r.jsxs)(n.p,{children:["Adding objects to an array, inserting objects at a given index, or replacing objects at a given index, can all\nlead to a crash when the object is ",(0,r.jsx)(n.code,{children:"nil"}),"."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objectivec",children:" [mArray addObject:nil]; //crash\n\n [mArray insertObject:nil atIndex:0]; //crash\n\n [mArray replaceObjectAtIndex:0 withObject:nil]; //crash\n"})}),"\n",(0,r.jsx)(n.h3,{id:"dictionaries",children:"Dictionaries"}),"\n",(0,r.jsxs)(n.p,{children:["Adding a ",(0,r.jsx)(n.code,{children:"nil"})," value in a dictionary causes a crash. If the concept of ",(0,r.jsx)(n.code,{children:"nil"})," is required, one can add\n",(0,r.jsx)(n.code,{children:"[NSNull null]"})," instead."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objectivec",children:' id value = nil;\n [mDict setObject:value forKey:@"somestring"]; //crash\n\n [mDict setObject:[NSNull null] forKey:@"somestring"]; //ok\n'})}),"\n",(0,r.jsxs)(n.p,{children:["Retrieving or removing an object from a dictionary with a ",(0,r.jsx)(n.code,{children:"nil"})," key also causes a crash:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objectivec",children:' id key = nil;\n mDict[key] = @"somestring"; //crash\n\n [mDict removeObjectForKey:nil]; //crash\n'})}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"Action"}),":"]}),"\n",(0,r.jsxs)(n.p,{children:["In all the cases above, when passing ",(0,r.jsx)(n.code,{children:"nil"})," causes a crash, the solutions are either making sure\nthat the object passed will never be ",(0,r.jsx)(n.code,{children:"nil"}),", or adding a check for ",(0,r.jsx)(n.code,{children:"nil"})," before calling those methods."]}),"\n",(0,r.jsx)(n.h2,{id:"nil_insertion_into_collection_latent",children:"NIL_INSERTION_INTO_COLLECTION_LATENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "Nil Insertion Into Collection" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A latent ",(0,r.jsx)(n.a,{href:"#nil_insertion_into_collection",children:"NIL_INSERTION_INTO_COLLECTION"}),". See the ",(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse#latent-issues",children:"documentation on Pulse latent issues"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"nil_messaging_to_non_pod",children:"NIL_MESSAGING_TO_NON_POD"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#memory-error",children:"Memory error"}),'. Reported as "Nil Messaging To Non Pod" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["In Objective-C, calling a method on ",(0,r.jsx)(n.code,{children:"nil"})," (or in Objective-C terms, sending a message to ",(0,r.jsx)(n.code,{children:"nil"}),") does not crash,\nit simply returns a falsy value (nil/0/false). However, sending a message that returns\na non-POD C++ type (POD being ",(0,r.jsx)(n.a,{href:"https://en.cppreference.com/w/cpp/named_req/PODType",children:'"Plain Old Data"'}),", essentially\nanything that cannot be compiled as a C-style struct) to ",(0,r.jsx)(n.code,{children:"nil"})," causes undefined behaviour."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objectivec",children:"std::shared_ptr callMethodReturnsnonPOD() {\n SomeObject* obj = getObjectOrNil();\n std::shared_ptr d = [obj returnsnonPOD]; // UB\n return d;\n}\n"})}),"\n",(0,r.jsxs)(n.p,{children:["To fix the above issue, we need to check if ",(0,r.jsx)(n.code,{children:"obj"})," is\nnot ",(0,r.jsx)(n.code,{children:"nil"})," before calling the ",(0,r.jsx)(n.code,{children:"returnsnonPOD"})," method:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objectivec",children:"std::shared_ptr callMethodReturnsnonPOD(bool b) {\n SomeObject* obj = getObjectOrNil(b);\n if (obj == nil) { return std::make_shared(0); }\n std::shared_ptr d = [obj returnsnonPOD];\n return d;\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"nil_messaging_to_non_pod_latent",children:"NIL_MESSAGING_TO_NON_POD_LATENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#memory-error",children:"Memory error"}),'. Reported as "Nil Messaging To Non Pod Latent" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A latent ",(0,r.jsx)(n.a,{href:"#nil_messaging_to_non_pod",children:"NIL_MESSAGING_TO_NON_POD"}),". See the ",(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse#latent-issues",children:"documentation on Pulse latent issues"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"no_matching_branch_in_try",children:"NO_MATCHING_BRANCH_IN_TRY"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "No Matching Branch In Try" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["No matching branch is found when evaluating the ",(0,r.jsx)(n.code,{children:"of"})," section of a ",(0,r.jsx)(n.code,{children:"try"})," expression. Corresponds to the ",(0,r.jsx)(n.code,{children:"{try_clause,V}"})," error in the Erlang runtime."]}),"\n",(0,r.jsxs)(n.p,{children:["For example, if we call ",(0,r.jsx)(n.code,{children:"tail([])"})," and the full definition of ",(0,r.jsx)(n.code,{children:"tail"})," is"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-erlang",children:"tail(X) ->\n try X of\n [_|T] -> {ok,T}\n catch\n _ -> error\n end.\n"})}),"\n",(0,r.jsx)(n.h2,{id:"no_matching_branch_in_try_latent",children:"NO_MATCHING_BRANCH_IN_TRY_LATENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "No Matching Branch In Try Latent" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A latent ",(0,r.jsx)(n.a,{href:"#no_matching_branch_in_try",children:"NO_MATCHING_BRANCH_IN_TRY"}),". See the ",(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse#latent-issues",children:"documentation on Pulse latent issues"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"no_matching_case_clause",children:"NO_MATCHING_CASE_CLAUSE"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "No Matching Case Clause" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["No matching case clause in Erlang: Reports an error when none of the clauses of a ",(0,r.jsx)(n.code,{children:"case"})," match the expression. Corresponds to the ",(0,r.jsx)(n.code,{children:"{case_clause,V}"})," error in the Erlang runtime."]}),"\n",(0,r.jsxs)(n.p,{children:["For example, if we call ",(0,r.jsx)(n.code,{children:"tail([])"})," and the full definition of ",(0,r.jsx)(n.code,{children:"tail"})," is"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-erlang",children:"tail(X) ->\n case X of\n [_|T] -> T\n end.\n"})}),"\n",(0,r.jsx)(n.p,{children:"This error is reported if either the pattern(s) or the guard(s) prevent matching any of the clauses."}),"\n",(0,r.jsx)(n.h2,{id:"no_matching_case_clause_latent",children:"NO_MATCHING_CASE_CLAUSE_LATENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "No Matching Case Clause Latent" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A latent ",(0,r.jsx)(n.a,{href:"#no_matching_case_clause",children:"NO_MATCHING_CASE_CLAUSE"}),". See the ",(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse#latent-issues",children:"documentation on Pulse latent issues"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"no_matching_else_clause",children:"NO_MATCHING_ELSE_CLAUSE"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "No Matching Else Clause" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["No matching else clause in Erlang: Reports an error when none of the clauses of an ",(0,r.jsx)(n.code,{children:"else"})," match the short-circuit result from ",(0,r.jsx)(n.code,{children:"maybe"})," body. Corresponds to the ",(0,r.jsx)(n.code,{children:"{else_clause,V}"})," error in the Erlang runtime."]}),"\n",(0,r.jsxs)(n.p,{children:["For example, here the ",(0,r.jsx)(n.code,{children:"1 ?= 2"})," expression does not match and short-circuits to ",(0,r.jsx)(n.code,{children:"2"}),", which does not match the single clause under ",(0,r.jsx)(n.code,{children:"else"}),":"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-erlang",children:"else_clause_error() ->\n maybe\n 1 ?= 2\n else\n 1 -> ok\n end.\n"})}),"\n",(0,r.jsx)(n.p,{children:"This error is reported if either the pattern(s) or the guard(s) prevent matching any of the clauses."}),"\n",(0,r.jsx)(n.h2,{id:"no_matching_else_clause_latent",children:"NO_MATCHING_ELSE_CLAUSE_LATENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "No Matching Else Clause Latent" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A latent ",(0,r.jsx)(n.a,{href:"#no_matching_else_clause",children:"NO_MATCHING_ELSE_CLAUSE"}),". See the ",(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse#latent-issues",children:"documentation on Pulse latent issues"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"no_matching_function_clause",children:"NO_MATCHING_FUNCTION_CLAUSE"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "No Matching Function Clause" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["No matching function clause in Erlang: Reports an error when none of the clauses of a function match the arguments of a call. Corresponds to the ",(0,r.jsx)(n.code,{children:"function_clause"})," error in the Erlang runtime."]}),"\n",(0,r.jsxs)(n.p,{children:["For example, if we call ",(0,r.jsx)(n.code,{children:"tail([])"})," and the full definition of ",(0,r.jsx)(n.code,{children:"tail"})," is"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-erlang",children:"tail([_|Xs]) -> Xs.\n"})}),"\n",(0,r.jsx)(n.p,{children:"This error is reported if either the pattern(s) or the guard(s) prevent matching any of the clauses."}),"\n",(0,r.jsx)(n.h2,{id:"no_matching_function_clause_latent",children:"NO_MATCHING_FUNCTION_CLAUSE_LATENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "No Matching Function Clause Latent" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A latent ",(0,r.jsx)(n.a,{href:"#no_matching_function_clause",children:"NO_MATCHING_FUNCTION_CLAUSE"}),". See the ",(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse#latent-issues",children:"documentation on Pulse latent issues"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"no_match_of_rhs",children:"NO_MATCH_OF_RHS"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "No Match Of Rhs" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["No match of right hand side value in Erlang: Reports an error when the right hand side value of a ",(0,r.jsx)(n.code,{children:"match"})," expression does not match the pattern on the left hand side. Corresponds to the ",(0,r.jsx)(n.code,{children:"{badmatch,V}"})," error in the Erlang runtime."]}),"\n",(0,r.jsxs)(n.p,{children:["For example, ",(0,r.jsx)(n.code,{children:"[H|T] = []"})," gives the error because the left hand side pattern requires at least one element in the list on the right hand side."]}),"\n",(0,r.jsx)(n.h2,{id:"no_match_of_rhs_latent",children:"NO_MATCH_OF_RHS_LATENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "No Match Of Rhs Latent" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A latent ",(0,r.jsx)(n.a,{href:"#no_match_of_rhs",children:"NO_MATCH_OF_RHS"}),". See the ",(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse#latent-issues",children:"documentation on Pulse latent issues"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"no_true_branch_in_if",children:"NO_TRUE_BRANCH_IN_IF"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "No True Branch In If" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["No true branch when evaluating an if expression in Erlang: Reports an error when none of the branches of an ",(0,r.jsx)(n.code,{children:"if"})," expression evaluate to true. Corresponds to the ",(0,r.jsx)(n.code,{children:"if_clause"})," error in the Erlang runtime."]}),"\n",(0,r.jsxs)(n.p,{children:["For example, if we call ",(0,r.jsx)(n.code,{children:"sign(0)"})," and the full definition of ",(0,r.jsx)(n.code,{children:"sign"})," is"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-erlang",children:"sign(X) ->\n if\n X > 0 -> positive;\n X < 0 -> negative\n end.\n"})}),"\n",(0,r.jsx)(n.h2,{id:"no_true_branch_in_if_latent",children:"NO_TRUE_BRANCH_IN_IF_LATENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "No True Branch In If Latent" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A latent ",(0,r.jsx)(n.a,{href:"#no_true_branch_in_if",children:"NO_TRUE_BRANCH_IN_IF"}),". See the ",(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse#latent-issues",children:"documentation on Pulse latent issues"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"nsstring_internal_ptr_captured_in_block",children:"NSSTRING_INTERNAL_PTR_CAPTURED_IN_BLOCK"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#memory-error",children:"Memory error"}),'. Reported as "NSString Captured in Block" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-self-in-block",children:"self-in-block"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This check flags when an internal pointer of a local variable of type ",(0,r.jsx)(n.code,{children:"std::string"})," is captured in an escaping block.\nThis means that the block will be leaving the current scope, i.e. it is\nnot annotated with ",(0,r.jsx)(n.code,{children:"__attribute__((noescape))"}),"."]}),"\n",(0,r.jsx)(n.p,{children:"Example:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:" std::string fullName;\n const char* c = fullName.c_str();\n dispatch_async(dispatch_get_main_queue(), ^{\n const char* c1 = c;\n });\n"})}),"\n",(0,r.jsx)(n.p,{children:"This could cause crashes because the variable is likely to be freed when the code is executed, leaving the pointer dangling."}),"\n",(0,r.jsx)(n.h2,{id:"nullptr_dereference",children:"NULLPTR_DEREFERENCE"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#null-pointer-dereference",children:"Null pointer dereference"}),'. Reported as "Null Dereference" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"Infer reports null dereference bugs in Java, C, C++, and Objective-C\nwhen it is possible that the null pointer is dereferenced, leading to\na crash."}),"\n",(0,r.jsx)(n.h3,{id:"null-dereference-in-java",children:"Null dereference in Java"}),"\n",(0,r.jsx)(n.p,{children:"Many of Infer's reports of potential Null Pointer Exceptions (NPE) come from code of the form"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:" p = foo(); // foo() might return null\n stuff();\n p.goo(); // dereferencing p, potential NPE\n"})}),"\n",(0,r.jsx)(n.p,{children:"If you see code of this form, then you have several options."}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsxs)(n.strong,{children:["If you are unsure whether or not ",(0,r.jsx)(n.code,{children:"foo()"})," will return null"]}),", you should\nideally either"]}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["Change the code to ensure that ",(0,r.jsx)(n.code,{children:"foo()"})," can not return null, or"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["Add a check that ",(0,r.jsx)(n.code,{children:"p"})," is not ",(0,r.jsx)(n.code,{children:"null"})," before dereferencing ",(0,r.jsx)(n.code,{children:"p"}),"."]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:["Sometimes, in case (2) it is not obvious what you should do when ",(0,r.jsx)(n.code,{children:"p"}),"\nis ",(0,r.jsx)(n.code,{children:"null"}),". One possibility is to throw an exception, failing early but\nexplicitly. This can be done using ",(0,r.jsx)(n.code,{children:"checkNotNull"})," as in the following\ncode:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"// code idiom for failing early\nimport static com.google.common.base.Preconditions.checkNotNull;\n\n //... intervening code\n\n p = checkNotNull(foo()); // foo() might return null\n stuff();\n p.goo(); // p cannot be null here\n"})}),"\n",(0,r.jsxs)(n.p,{children:["The call ",(0,r.jsx)(n.code,{children:"checkNotNull(foo())"})," will never return ",(0,r.jsx)(n.code,{children:"null"}),": if ",(0,r.jsx)(n.code,{children:"foo()"}),"\nreturns ",(0,r.jsx)(n.code,{children:"null"})," then it fails early by throwing a Null Pointer\nException."]}),"\n",(0,r.jsxs)(n.p,{children:["Facebook NOTE: ",(0,r.jsx)(n.strong,{children:"If you are absolutely sure that foo() will not be\nnull"}),", then if you land your diff this case will no longer be\nreported after your diff makes it to trunk."]}),"\n",(0,r.jsx)(n.h3,{id:"null-dereference-in-c",children:"Null dereference in C"}),"\n",(0,r.jsx)(n.p,{children:"Here is an example of an inter-procedural null dereference bug in C:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-c",children:"struct Person {\n int age;\n int height;\n int weight;\n};\nint get_age(struct Person *who) {\n return who->age;\n}\nint null_pointer_interproc() {\n struct Person *joe = 0;\n return get_age(joe);\n}\n"})}),"\n",(0,r.jsx)(n.h3,{id:"null-dereference-in-objective-c",children:"Null dereference in Objective-C"}),"\n",(0,r.jsxs)(n.p,{children:["In Objective-C, null dereferences are less common than in Java, but they still\nhappen and their cause can be hidden. In general, passing a message to nil does\nnot cause a crash and returns ",(0,r.jsx)(n.code,{children:"nil"}),", but dereferencing a pointer directly does\ncause a crash."]}),"\n",(0,r.jsx)(n.p,{children:"Example:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objectivec",children:"(int) foo:(C*) param { // passing nil\n D* d = [param bar]; // nil message passing\n return d->fld; // crash\n}\n(void) callFoo {\n C* c = [self bar]; // returns nil\n [foo:c]; // crash reported here\n}\n"})}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"Action"}),":\nAdding a ",(0,r.jsx)(n.code,{children:"nil"})," check either for ",(0,r.jsx)(n.code,{children:"param"})," above or for ",(0,r.jsx)(n.code,{children:"d"}),", or making sure that ",(0,r.jsx)(n.code,{children:"foo:"})," will never\nbe called with ",(0,r.jsx)(n.code,{children:"nil"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["Calling a ",(0,r.jsx)(n.code,{children:"nil"})," block will also cause a crash.\nWe have a dedicated issue type for this case: ",(0,r.jsx)(n.a,{href:"/docs/next/all-issue-types#nil_block_call",children:"Nil Block Call"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["Moreover, inserting ",(0,r.jsx)(n.code,{children:"nil"})," into a collection will cause a crash as well. We\nalso have a dedicated issue type for this case:\n",(0,r.jsx)(n.a,{href:"/docs/next/all-issue-types#nil_insertion_into_collection",children:"Nil Insertion Into Collection"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"nullptr_dereference_in_nullsafe_class",children:"NULLPTR_DEREFERENCE_IN_NULLSAFE_CLASS"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#null-pointer-dereference",children:"Null pointer dereference"}),'. Reported as "Null Dereference" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"Infer reports null dereference bugs in Java, C, C++, and Objective-C\nwhen it is possible that the null pointer is dereferenced, leading to\na crash."}),"\n",(0,r.jsx)(n.h3,{id:"null-dereference-in-java-1",children:"Null dereference in Java"}),"\n",(0,r.jsx)(n.p,{children:"Many of Infer's reports of potential Null Pointer Exceptions (NPE) come from code of the form"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:" p = foo(); // foo() might return null\n stuff();\n p.goo(); // dereferencing p, potential NPE\n"})}),"\n",(0,r.jsx)(n.p,{children:"If you see code of this form, then you have several options."}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsxs)(n.strong,{children:["If you are unsure whether or not ",(0,r.jsx)(n.code,{children:"foo()"})," will return null"]}),", you should\nideally either"]}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["Change the code to ensure that ",(0,r.jsx)(n.code,{children:"foo()"})," can not return null, or"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["Add a check that ",(0,r.jsx)(n.code,{children:"p"})," is not ",(0,r.jsx)(n.code,{children:"null"})," before dereferencing ",(0,r.jsx)(n.code,{children:"p"}),"."]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:["Sometimes, in case (2) it is not obvious what you should do when ",(0,r.jsx)(n.code,{children:"p"}),"\nis ",(0,r.jsx)(n.code,{children:"null"}),". One possibility is to throw an exception, failing early but\nexplicitly. This can be done using ",(0,r.jsx)(n.code,{children:"checkNotNull"})," as in the following\ncode:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"// code idiom for failing early\nimport static com.google.common.base.Preconditions.checkNotNull;\n\n //... intervening code\n\n p = checkNotNull(foo()); // foo() might return null\n stuff();\n p.goo(); // p cannot be null here\n"})}),"\n",(0,r.jsxs)(n.p,{children:["The call ",(0,r.jsx)(n.code,{children:"checkNotNull(foo())"})," will never return ",(0,r.jsx)(n.code,{children:"null"}),": if ",(0,r.jsx)(n.code,{children:"foo()"}),"\nreturns ",(0,r.jsx)(n.code,{children:"null"})," then it fails early by throwing a Null Pointer\nException."]}),"\n",(0,r.jsxs)(n.p,{children:["Facebook NOTE: ",(0,r.jsx)(n.strong,{children:"If you are absolutely sure that foo() will not be\nnull"}),", then if you land your diff this case will no longer be\nreported after your diff makes it to trunk."]}),"\n",(0,r.jsx)(n.h3,{id:"null-dereference-in-c-1",children:"Null dereference in C"}),"\n",(0,r.jsx)(n.p,{children:"Here is an example of an inter-procedural null dereference bug in C:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-c",children:"struct Person {\n int age;\n int height;\n int weight;\n};\nint get_age(struct Person *who) {\n return who->age;\n}\nint null_pointer_interproc() {\n struct Person *joe = 0;\n return get_age(joe);\n}\n"})}),"\n",(0,r.jsx)(n.h3,{id:"null-dereference-in-objective-c-1",children:"Null dereference in Objective-C"}),"\n",(0,r.jsxs)(n.p,{children:["In Objective-C, null dereferences are less common than in Java, but they still\nhappen and their cause can be hidden. In general, passing a message to nil does\nnot cause a crash and returns ",(0,r.jsx)(n.code,{children:"nil"}),", but dereferencing a pointer directly does\ncause a crash."]}),"\n",(0,r.jsx)(n.p,{children:"Example:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objectivec",children:"(int) foo:(C*) param { // passing nil\n D* d = [param bar]; // nil message passing\n return d->fld; // crash\n}\n(void) callFoo {\n C* c = [self bar]; // returns nil\n [foo:c]; // crash reported here\n}\n"})}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"Action"}),":\nAdding a ",(0,r.jsx)(n.code,{children:"nil"})," check either for ",(0,r.jsx)(n.code,{children:"param"})," above or for ",(0,r.jsx)(n.code,{children:"d"}),", or making sure that ",(0,r.jsx)(n.code,{children:"foo:"})," will never\nbe called with ",(0,r.jsx)(n.code,{children:"nil"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["Calling a ",(0,r.jsx)(n.code,{children:"nil"})," block will also cause a crash.\nWe have a dedicated issue type for this case: ",(0,r.jsx)(n.a,{href:"/docs/next/all-issue-types#nil_block_call",children:"Nil Block Call"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["Moreover, inserting ",(0,r.jsx)(n.code,{children:"nil"})," into a collection will cause a crash as well. We\nalso have a dedicated issue type for this case:\n",(0,r.jsx)(n.a,{href:"/docs/next/all-issue-types#nil_insertion_into_collection",children:"Nil Insertion Into Collection"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"nullptr_dereference_in_nullsafe_class_latent",children:"NULLPTR_DEREFERENCE_IN_NULLSAFE_CLASS_LATENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#null-pointer-dereference",children:"Null pointer dereference"}),'. Reported as "Null Dereference" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A latent ",(0,r.jsx)(n.a,{href:"#nullptr_dereference_in_nullsafe_class",children:"NULLPTR_DEREFERENCE_IN_NULLSAFE_CLASS"}),". See the ",(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse#latent-issues",children:"documentation on Pulse latent issues"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"nullptr_dereference_latent",children:"NULLPTR_DEREFERENCE_LATENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#null-pointer-dereference",children:"Null pointer dereference"}),'. Reported as "Null Dereference" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A latent ",(0,r.jsx)(n.a,{href:"#nullptr_dereference",children:"NULLPTR_DEREFERENCE"}),". See the ",(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse#latent-issues",children:"documentation on Pulse latent issues"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"null_argument",children:"NULL_ARGUMENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "Null Argument" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objc",children:"This issue type indicates `nil` being passed as argument where a non-nil value expected.\n\n#import \n\n// Test (non-nil) returned values of NSString methods against `nil`\nNSString* stringNotNil(NSString* str) {\n if (!str) {\n // ERROR: NSString:stringWithString: expects a non-nil value\n\treturn [NSString stringWithString:nil];\n }\n return str;\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"null_argument_latent",children:"NULL_ARGUMENT_LATENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "Null Argument Latent" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A latent ",(0,r.jsx)(n.a,{href:"#null_argument",children:"NULL_ARGUMENT"}),". See the ",(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse#latent-issues",children:"documentation on Pulse latent issues"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"null_dereference",children:"NULL_DEREFERENCE"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#null-pointer-dereference",children:"Null pointer dereference"}),'. Reported as "Null Dereference" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-biabduction",children:"biabduction"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["See ",(0,r.jsx)(n.a,{href:"#nullptr_dereference",children:"NULLPTR_DEREFERENCE"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"optional_empty_access",children:"OPTIONAL_EMPTY_ACCESS"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "Optional Empty Access" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["Optional Empty Access warnings are reported when we try to retrieve the value of a ",(0,r.jsx)(n.a,{href:"https://github.com/facebook/folly/blob/master/folly/Optional.h",children:(0,r.jsx)(n.code,{children:"folly::Optional"})})," when it is empty (i.e. ",(0,r.jsx)(n.code,{children:"folly::none"}),")."]}),"\n",(0,r.jsxs)(n.p,{children:["In the following example we get a warning as ",(0,r.jsx)(n.code,{children:"int_opt"})," might be ",(0,r.jsx)(n.code,{children:"folly::none"})," and its value is being accessed:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-cpp",children:"bool somef(int v);\n\nfolly::Optional mightReturnNone(int v) {\n if (somef(v)) {\n return folly::Optional(v);\n }\n\n return folly::none;\n}\n\nint value_no_check() {\n folly::Optional int_opt = mightReturnNone (4);\n return int_opt.value(); // Optional Empty Access warning\n}\n"})}),"\n",(0,r.jsxs)(n.p,{children:["We do not get the warning anymore if we add a check whether ",(0,r.jsx)(n.code,{children:"int_opt"})," is not empty:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-cpp",children:"int value_check() {\n folly::Optional int_opt = mightReturnNone (4);\n if (int_opt.has_value()) {\n return int_opt.value(); // OK\n }\n return -1;\n}\n"})}),"\n",(0,r.jsx)(n.p,{children:"In some cases we know that we have a non-empty value and there is no need to have a check. Consider the following example where Infer does not warn:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-cpp",children:"bool somef(int v) {return v > 3;};\n\nfolly::Optional mightReturnNone(int v) {\n if (somef(v)) {\n return folly::Optional(v);\n }\n\n return folly::none;\n}\n\nint value_no_check() {\n folly::Optional int_opt = mightReturnNone (4); // cannot be folly::none\n return int_opt.value(); // OK\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"optional_empty_access_latent",children:"OPTIONAL_EMPTY_ACCESS_LATENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "Optional Empty Access Latent" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A latent ",(0,r.jsx)(n.a,{href:"#optional_empty_access",children:"OPTIONAL_EMPTY_ACCESS"}),". See the ",(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse#latent-issues",children:"documentation on Pulse latent issues"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"premature_nil_termination_argument",children:"PREMATURE_NIL_TERMINATION_ARGUMENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Premature Nil Termination Argument" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-biabduction",children:"biabduction"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This error type is reported in C and Objective-C. In many variadic methods,\n",(0,r.jsx)(n.code,{children:"nil"})," is used to signify the end of the list of input objects. This is similar\nto nil-termination of C strings. If one of the arguments that is not the last\nargument to the method is ",(0,r.jsx)(n.code,{children:"nil"})," as well, Infer reports an error because that may\nlead to unexpected behavior."]}),"\n",(0,r.jsxs)(n.p,{children:["An example of such variadic methods is\n",(0,r.jsx)(n.a,{href:"https://developer.apple.com/library/prerelease/ios/documentation/Cocoa/Reference/Foundation/Classes/NSArray_Class/index.html#//apple_ref/occ/clm/NSArray/arrayWithObjects",children:"arrayWithObjects"})]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objectivec",children:' NSArray *foo = [NSArray arrayWithObjects: @"aaa", str, @"bbb", nil];\n'})}),"\n",(0,r.jsxs)(n.p,{children:["In this example, if ",(0,r.jsx)(n.code,{children:"str"})," is ",(0,r.jsx)(n.code,{children:"nil"})," then an array ",(0,r.jsx)(n.code,{children:'@[@"aaa"]'})," of size 1 will be\ncreated, and not an array ",(0,r.jsx)(n.code,{children:'@[@"aaa", str, @"bbb"]'})," of size 3 as expected."]}),"\n",(0,r.jsx)(n.h2,{id:"pulse_cannot_instantiate_abstract_class",children:"PULSE_CANNOT_INSTANTIATE_ABSTRACT_CLASS"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "Cannot Instantiate Abstract Class" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["Instantiating an abstract class will lead to ",(0,r.jsx)(n.code,{children:"Cannot instantiate abstract class"})," error."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-hack",children:"abstract class AbstractClass1 {}\n\nclass ConcreteClass1 extends AbstractClass1 {}\n\npublic static function makeGeneric(classname $cls): void {\n new $cls();\n}\n\n<<__ConsistentConstruct>>\nabstract class AbstractClass2 {\n\n public static function makeStatic(): void {\n new static();\n }\n}\n\nclass ConcreteClass2 extends AbstractClass2 {}\n\npublic function badViaGeneric(): void {\n Main::makeGeneric(AbstractClass1::class); // ERROR!\n}\n\npublic function goodViaGeneric(): void {\n Main::makeGeneric(ConcreteClass1::class);\n}\n\npublic function badViaStatic(): void {\n AbstractClass2::makeStatic(); // ERROR!\n}\n\npublic function goodViaStatic(): void {\n ConcreteClass2::makeStatic();\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"pulse_const_refable",children:"PULSE_CONST_REFABLE"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#perf-regression",children:"Perf regression"}),'. Reported as "Const Refable Parameter" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This issue is reported when a function parameter is a) passed by value and b) is not modified inside the function. Instead, parameter can be passed by const reference, i.e. converted to a ",(0,r.jsx)(n.code,{children:"const&"})," so that no unnecessary copy is created at the callsite of the function."]}),"\n",(0,r.jsx)(n.p,{children:"For example,"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-cpp",children:"#include \n\nint read_first(const std::vector& vec) { return vec[0]; }\n\nvoid const_refable(std::vector vec) {\n int first = read_first(vec); // vec is never modified, so the parameter should have type const&\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"pulse_dict_missing_key",children:"PULSE_DICT_MISSING_KEY"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "Dict Missing Key" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This issue is similar to ",(0,r.jsx)(n.a,{href:"#pulse_uninitialized_value",children:(0,r.jsx)(n.code,{children:"PULSE_UNINITIALIZED_VALUE"})}),", but it is to warn\nreading a missing key of dictionary in Hack."]}),"\n",(0,r.jsxs)(n.p,{children:["For example, in the following code, the dictionary ",(0,r.jsx)(n.code,{children:"$d"})," has no entry for ",(0,r.jsx)(n.code,{children:"bye"}),", so reading\n",(0,r.jsx)(n.code,{children:"$d['bye']"})," will throw the ",(0,r.jsx)(n.code,{children:"OutOfBoundsException"})," exception, which is usually unexpected from\ndevelopers. We can use a safer function ",(0,r.jsx)(n.code,{children:"idx"})," instead when keys of a dictionary is unclear."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-hack",children:"function simple_bad() : int {\n $d = dict['hi' => 42, 'hello' => 52];\n return $d['bye'];\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"pulse_dynamic_type_mismatch",children:"PULSE_DYNAMIC_TYPE_MISMATCH"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "Dynamic Type Mismatch" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"This error is reported in Hack. It fires when we detect an operation that is incompatible\nwith the dynamic type of its arguments."}),"\n",(0,r.jsxs)(n.p,{children:["For example, reading ",(0,r.jsx)(n.code,{children:"$x['key']"})," when ",(0,r.jsx)(n.code,{children:"$x"})," is a vector."]}),"\n",(0,r.jsx)(n.h2,{id:"pulse_readonly_shared_ptr_param",children:"PULSE_READONLY_SHARED_PTR_PARAM"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#perf-regression",children:"Perf regression"}),'. Reported as "Read-only Shared Parameter" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This issue is reported when a shared pointer parameter is a) passed by value and b) is used only for reading, rather than lifetime extension. At the callsite, this might cause a potentially expensive unnecessary copy of the shared pointer, especially when many number of threads are sharing it. To avoid this, consider 1) passing the raw pointer instead and 2) use ",(0,r.jsx)(n.code,{children:"std::shared_ptr::get"})," at callsites."]}),"\n",(0,r.jsx)(n.p,{children:"For example,"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-cpp",children:"void callee(std::shared_ptr x) {\n // read_T(*x);\n}\n\nvoid caller() {\n callee(shared_ptr);\n}\n"})}),"\n",(0,r.jsx)(n.p,{children:"can be changed to"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-cpp",children:"void callee(T* p) {\n // read_T(*p);\n}\n\nvoid caller() {\n callee(shared_ptr.get());\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"pulse_reference_stability",children:"PULSE_REFERENCE_STABILITY"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#memory-error",children:"Memory error"}),'. Reported as "Reference Stability" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["The family of maps ",(0,r.jsx)(n.code,{children:"folly::F14ValueMap"}),", ",(0,r.jsx)(n.code,{children:"folly::F14VectorMap"}),", and by extension\n",(0,r.jsx)(n.code,{children:"folly::F14FastMap"})," differs slightly from ",(0,r.jsx)(n.code,{children:"std::unordered_map"})," as it does not\nprovide reference stability. When the map resizes such as when ",(0,r.jsx)(n.code,{children:"reserve"})," is\ncalled or new elements are added, all existing references become invalid and\nshould not be used."]}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"operator[]"})," is an interesting case as it can easily introduce unsafe code when\nused twice in the same expression. Depending on what keys are present and which\norder the compiler sequences sub-expressions, an insert via ",(0,r.jsx)(n.code,{children:"operator[]"})," can\ninvalidate a reference obtained in the same expression before it's read from.\nTypically, those cases can be improved by using other map functions such as\n",(0,r.jsx)(n.code,{children:"at"}),", ",(0,r.jsx)(n.code,{children:"find"}),", ",(0,r.jsx)(n.code,{children:"emplace"}),", or ",(0,r.jsx)(n.code,{children:"insert_or_assign"})," to increase code quality and\nsafety."]}),"\n",(0,r.jsx)(n.p,{children:"Examples:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-cpp",children:"#include \n\nvoid use_reference_after_growth_bad(folly::F14FastMap& map) {\n const auto& valueRef = map.at(1);\n map.emplace(13, 71);\n const auto valueCopy = valueRef;\n}\n\nvoid unsafe_expressions_bad(folly::F14FastMap& map) {\n // Unsafe expressions in situations where one or both keys are not present.\n map[13] = map[71];\n const auto p = map[13] * map[71];\n const auto q = f(map[13], map[71]);\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"pulse_resource_leak",children:"PULSE_RESOURCE_LEAK"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#resource-leak",children:"Resource leak"}),'. Reported as "Resource Leak" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["See ",(0,r.jsx)(n.a,{href:"#resource_leak",children:"RESOURCE_LEAK"})]}),"\n",(0,r.jsx)(n.h2,{id:"pulse_transitive_access",children:"PULSE_TRANSITIVE_ACCESS"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#logic-error",children:"Logic error"}),'. Reported as "Transitive Access" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"This issue tracks spurious accesses that are reachable from specific entry functions."}),"\n",(0,r.jsx)(n.p,{children:"Spurious accesses are specified as specific load/calls."}),"\n",(0,r.jsx)(n.p,{children:"Entry functions are specified through their enclosing class that must extend a specific\nclass and should not extend a list of specific classes."}),"\n",(0,r.jsx)(n.h2,{id:"pulse_unawaited_awaitable",children:"PULSE_UNAWAITED_AWAITABLE"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#resource-leak",children:"Resource leak"}),'. Reported as "Unawaited Awaitable" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"Awaitable"})," values created by calls to asynchronous methods should eventually be ",(0,r.jsx)(n.code,{children:"await"}),"ed along all codepaths (even if their value is unused). Hence the following is ",(0,r.jsx)(n.em,{children:"not"})," OK"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-hack",children:"class A {\n public static async genInt() : Awaitable{\n // typically do something involving IO\n }\n\n public static async genBad() : Awaitable {\n $_unused = self::genInt(); // ERROR: should have done $_unused = await self::genInt();\n return;\n }\n}\n"})}),"\n",(0,r.jsxs)(n.p,{children:["Failure to ",(0,r.jsx)(n.code,{children:"await"})," an ",(0,r.jsx)(n.code,{children:"Awaitable"})," can lead to non-deterministic amount of the asynchronous call actually being executed, and can also indicate a logical confusion between ",(0,r.jsx)(n.code,{children:"T"})," and ",(0,r.jsx)(n.code,{children:"Awaitable"})," that may not be caught by the type-checker."]}),"\n",(0,r.jsx)(n.h2,{id:"pulse_unfinished_builder",children:"PULSE_UNFINISHED_BUILDER"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#resource-leak",children:"Resource leak"}),'. Reported as "Unfinished Builder" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"Classes adhering to builder pattern are usually expected to call a finalizer function at some point to produce final result based on values that were passed to a builder itself. If finalizer function hasn't been called then builder's data won't be consumed in any meaningful way and will just be discarded."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-hack",children:"class MyBuilder {\n private int $a = 0;\n private int $b = 0;\n\n public function setA(int $a): MyBuilder {\n $this->a = $a;\n return $this;\n }\n\n public function setB(int $b): MyBuilder {\n $this->b = $b;\n return $this;\n }\n\n public function saveX(): Awaitable {\n // typically do something involving IO\n }\n}\n\nclass BuilderTester {\n public static function builderUserOK(): void {\n $b = new MyBuilder(0);\n $b->setA(42)->setB(97)->saveX();\n }\n\n public static function builderUserBad(): void {\n $b = new MyBuilder(0);\n $b->setA(42)->setB(97); // ERROR: saveX hasn't been called so the builder's data is discarded\n }\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"pulse_uninitialized_const",children:"PULSE_UNINITIALIZED_CONST"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "Uninitialized Const" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This issue is similar to ",(0,r.jsx)(n.a,{href:"#pulse_uninitialized_value",children:(0,r.jsx)(n.code,{children:"PULSE_UNINITIALIZED_VALUE"})}),", but it is to detect the uninitialized abstract const value in Hack."]}),"\n",(0,r.jsxs)(n.p,{children:["For example, in the following code, the ",(0,r.jsx)(n.code,{children:"FIELD"})," can be read by the static method ",(0,r.jsx)(n.code,{children:"get_field"}),"."]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["It is problematic invoking ",(0,r.jsx)(n.code,{children:"static::FIELD"}),", since it may be resolved to a ",(0,r.jsx)(n.code,{children:"A::FIELD"})," access, if called from ",(0,r.jsx)(n.code,{children:"A::get_field()"}),". Because ",(0,r.jsx)(n.code,{children:"FIELD"})," is abstract in ",(0,r.jsx)(n.code,{children:"A"}),", it is never assigned a value and the vm will crash. Unfortunately, Hack's type system cannot catch this."]}),"\n",(0,r.jsxs)(n.li,{children:["In the ",(0,r.jsx)(n.code,{children:"B"})," class, ",(0,r.jsx)(n.code,{children:"FIELD"})," is initialized, thus invoking ",(0,r.jsx)(n.code,{children:"B::get_field"})," is safe."]}),"\n"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-hack",children:'abstract class A {\n abstract const string FIELD;\n \n public static function get_field(): string {\n return static::FIELD;\n }\n}\n\nfunction call_get_field_bad(): string {\n return A::get_field();\n}\n\nclass B extends A {\n const string FIELD = "defined";\n}\n\nfunction call_get_field_ok(): string {\n return B::get_field();\n}\n'})}),"\n",(0,r.jsx)(n.h2,{id:"pulse_uninitialized_method",children:"PULSE_UNINITIALIZED_METHOD"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "Uninitialized Method" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This issue is similar to ",(0,r.jsx)(n.a,{href:"#pulse_uninitialized_const",children:(0,r.jsx)(n.code,{children:"PULSE_UNINITIALIZED_CONST"})}),", but it is to detect the uninitialized method call in Hack."]}),"\n",(0,r.jsxs)(n.p,{children:["For example, in the following code, the static method ",(0,r.jsx)(n.code,{children:"foo"})," is declared only in the interface and the abstract class. Thus, calling the static method can introduce an unexpected exception or a fatal error, while the type checker does miss the issue."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-hack",children:"interface MyInterface {\n public static function foo(): string;\n}\n\nabstract class MyAbstractClass {\n public abstract static function foo(): string;\n}\n\nfunction interface_method_static_method_bad(): string {\n // Uncaught exception 'TypehintViolationException'\n $c = MyInterface::class;\n return $c::foo();\n}\n\nfunction abstract_class_static_method_bad(): string {\n // Fatal error: Cannot call abstract method\n $c = MyAbstractClass::class;\n return $c::foo();\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"pulse_uninitialized_value",children:"PULSE_UNINITIALIZED_VALUE"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#memory-error",children:"Memory error"}),'. Reported as "Uninitialized Value" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"The code uses a variable that has not been initialized, leading to unpredictable or unintended results."}),"\n",(0,r.jsx)(n.p,{children:"Using uninitialized values can lead to undefined behaviors possibly resulting in crashes, security failures and invalid results."}),"\n",(0,r.jsx)(n.p,{children:"This can easily be fixed by assigning all variables to an initial value when declaring them."}),"\n",(0,r.jsx)(n.p,{children:"This, for example, in C:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-c",children:"struct coordinates {\n int x;\n int y;\n};\n\nvoid foo() {\n struct coordinates c;\n c.x = 42;\n c.y++; // uninitialized value c.y!\n\n int z;\n if (z == 0) { // uninitialized value z!\n // something\n }\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"pulse_unnecessary_copy",children:"PULSE_UNNECESSARY_COPY"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#perf-regression",children:"Perf regression"}),'. Reported as "Unnecessary Copy" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"This is reported when Infer detects an unnecessary copy of an object via copy constructor where neither the source nor the copied variable are modified before the variable goes out of scope. Rather than the copy, a reference to the source object could be used to save memory."}),"\n",(0,r.jsx)(n.p,{children:"For example,"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-cpp",children:"struct A {\n int a;\n};\n\nint unnecessary_copy(A& x){\n auto y = x; // calls copy constructor\n return y.a; // y is not modified after copy, hence we could avoid the copy by adding & after auto as below\n}\n\nint use_reference_instead(A& x){\n auto& y = x; // copy the ref only\n return y.a;\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"pulse_unnecessary_copy_assignment",children:"PULSE_UNNECESSARY_COPY_ASSIGNMENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#perf-regression",children:"Perf regression"}),'. Reported as "Unnecessary Copy Assignment" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["See ",(0,r.jsx)(n.a,{href:"#pulse_unnecessary_copy",children:"PULSE_UNNECESSARY_COPY"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"pulse_unnecessary_copy_assignment_const",children:"PULSE_UNNECESSARY_COPY_ASSIGNMENT_CONST"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#perf-regression",children:"Perf regression"}),'. Reported as "Unnecessary Copy Assignment from Const" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["See ",(0,r.jsx)(n.a,{href:"#pulse_unnecessary_copy",children:"PULSE_UNNECESSARY_COPY"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"pulse_unnecessary_copy_assignment_movable",children:"PULSE_UNNECESSARY_COPY_ASSIGNMENT_MOVABLE"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#perf-regression",children:"Perf regression"}),'. Reported as "Unnecessary Copy Assignment Movable" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["See ",(0,r.jsx)(n.a,{href:"#pulse_unnecessary_copy_movable",children:"PULSE_UNNECESSARY_COPY_MOVABLE"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"pulse_unnecessary_copy_intermediate",children:"PULSE_UNNECESSARY_COPY_INTERMEDIATE"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#perf-regression",children:"Perf regression"}),'. Reported as "Unnecessary Copy Intermediate" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This is reported when Infer detects an unnecessary temporary copy of an intermediate object where copy is created to be passed down to a function unnecessarily. Instead, the intermediate object should either be moved into the callee or the type of the callee's parameter should be made ",(0,r.jsx)(n.code,{children:"const &"}),"."]}),"\n",(0,r.jsx)(n.p,{children:"A prime example of this occurs when we call a function with a call-by-value parameter as follows:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-cpp",children:"void callee(ExpensiveObject obj) {\n // ....\n}\n\nvoid caller() {\n callee(myExpensiveObj); // a copy of myExpensiveObj is created\n // the copy is destroyed right after the call \n}\n"})}),"\n",(0,r.jsxs)(n.p,{children:["In this case, when we call ",(0,r.jsx)(n.code,{children:"callee"}),", under the hood, a copy of the argument ",(0,r.jsx)(n.code,{children:"myExpensiveObj"})," is created to be passed to the function call. However, the copy might be unnecessary if"]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"callee"})," doesn\u2019t modify its parameter \u2192 then we can change its type to ",(0,r.jsx)(n.code,{children:"const ExpensiveObject&"}),", getting rid of the copy at caller"]}),"\n",(0,r.jsxs)(n.li,{children:["even if ",(0,r.jsx)(n.code,{children:"callee"})," might modify the object, if the argument ",(0,r.jsx)(n.code,{children:"myExpensiveObj"})," is never used later on, we can get rid of the copy by moving it instead: ",(0,r.jsx)(n.code,{children:"callee(std::move(myExpensiveObj))"}),"."]}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:["The analysis is careful about suggesting moves blindly though: if the argument ",(0,r.jsx)(n.code,{children:"myExpensiveObj"})," is of type ",(0,r.jsx)(n.code,{children:"const & ExpensiveObject"})," then we also recommend that for move to work, const-reference needs to be removed."]}),"\n",(0,r.jsx)(n.p,{children:"PS: We check for other conditions on the argument here: e.g. it should be local to the procedure, as moving a non-local member might cause other memory correctness issues like use-after-move later on."}),"\n",(0,r.jsx)(n.h2,{id:"pulse_unnecessary_copy_intermediate_const",children:"PULSE_UNNECESSARY_COPY_INTERMEDIATE_CONST"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#perf-regression",children:"Perf regression"}),'. Reported as "Unnecessary Copy Intermediate from Const" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["See ",(0,r.jsx)(n.a,{href:"#pulse_unnecessary_copy",children:"PULSE_UNNECESSARY_COPY"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"pulse_unnecessary_copy_movable",children:"PULSE_UNNECESSARY_COPY_MOVABLE"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#perf-regression",children:"Perf regression"}),'. Reported as "Unnecessary Copy Movable" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"This is reported when Infer detects an unnecessary copy into a field where"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"the source is an rvalue-reference"}),"\n",(0,r.jsx)(n.li,{children:"the source is not modified before it goes out of scope or is destroyed."}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"Note that the copy can be modified since it has the ownership of the object."}),"\n",(0,r.jsx)(n.p,{children:"Fix: Rather than the copying into the field, the source should be moved into it."}),"\n",(0,r.jsx)(n.p,{children:"For example,"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-cpp",children:"struct A {\n std::vector vec;\n};\n\nclass Test {\n A mem_a;\n\n void unnecessary_copy(A&& src) {\n mem_a = src;\n // fix is to move as follows\n // mem_a = std::move(src);\n }\n\n};\n\n"})}),"\n",(0,r.jsx)(n.h2,{id:"pulse_unnecessary_copy_optional",children:"PULSE_UNNECESSARY_COPY_OPTIONAL"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#perf-regression",children:"Perf regression"}),'. Reported as "Unnecessary Copy to Optional" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This is reported when Infer detects an unnecessary copy of an object via ",(0,r.jsx)(n.code,{children:"optional"})," value\nconstruction where the source is not modified before it goes out of scope. To avoid the copy, we\ncan move the source object or change the callee's type."]}),"\n",(0,r.jsx)(n.p,{children:"For example,"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-cpp",children:"void get_optional_value(std::optional x) {}\n\nvoid pass_non_optional_value(A x) {\n get_optional_value(x);\n // fix is to move as follows\n // get_optional_value(std::move(x));\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"pulse_unnecessary_copy_optional_const",children:"PULSE_UNNECESSARY_COPY_OPTIONAL_CONST"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#perf-regression",children:"Perf regression"}),'. Reported as "Unnecessary Copy to Optional from Const" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["See ",(0,r.jsx)(n.a,{href:"#pulse_unnecessary_copy_optional",children:"PULSE_UNNECESSARY_COPY_OPTIONAL"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"pulse_unnecessary_copy_return",children:"PULSE_UNNECESSARY_COPY_RETURN"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#perf-regression",children:"Perf regression"}),'. Reported as "Unnecessary Copy Return" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This is similar to ",(0,r.jsx)(n.a,{href:"#pulse_unnecessary_copy",children:"PULSE_UNNECESSARY_COPY"}),", but reported when a callee returns a copied value and it is not modified in its caller. We may be able to return const-ref typed value or try ",(0,r.jsx)(n.code,{children:"std::move"})," to avoid the copy."]}),"\n",(0,r.jsx)(n.p,{children:"For example,"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-cpp",children:"class MyClass {\n T v;\n public:\n T get() {\n return v; // v is copied here, which is avoidable.\n }\n};\n\nvoid caller(MyClass obj) {\n T x = obj.get();\n std::cout << x; // x is not modified.\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"pulse_unnecessary_copy_thrift_assignment",children:"PULSE_UNNECESSARY_COPY_THRIFT_ASSIGNMENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#perf-regression",children:"Perf regression"}),'. Reported as "Unnecessary Copy Assignment into Thrift" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This is similar to ",(0,r.jsx)(n.a,{href:"#pulse_unnecessary_copy_assignment",children:"PULSE_UNNECESSARY_COPY_ASSIGNMENT"}),", but is\nreported when copied into thrift fields."]}),"\n",(0,r.jsx)(n.h2,{id:"pure_function",children:"PURE_FUNCTION"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Pure Function" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-purity",children:"purity"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"This issue type indicates pure functions. For instance, below functions would be marked as pure:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"int local_write_pure(int x, int y) {\n int k = x + y;\n k++;\n return k;\n}\n\n// no change to outside state, the local allocation is ok.\nint local_alloc_pure(ArrayList list) {\n ArrayList list_new = new ArrayList();\n for (Integer el : list) {\n list_new.add(el);\n }\n return list_new.size();\n}\n"})}),"\n",(0,r.jsx)(n.p,{children:"However, the following ones would not be pure:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"void swap_impure(int[] array, int i, int j) {\n int tmp = array[i];\n array[i] = array[j]; // modifying the input array\n array[j] = tmp;\n}\n\nint a = 0;\nvoid set_impure(int x, int y) {\n a = x + y; //modifying a global variable\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"regex_op_on_ui_thread",children:"REGEX_OP_ON_UI_THREAD"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#perf-regression",children:"Perf regression"}),'. Reported as "Regex Op On Ui Thread" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-starvation",children:"starvation"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"A potentially costly operation on a regular expression occurs on the UI thread."}),"\n",(0,r.jsx)(n.h2,{id:"resource_leak",children:"RESOURCE_LEAK"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#resource-leak",children:"Resource leak"}),'. Reported as "Resource Leak" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-biabduction",children:"biabduction"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"Infer reports resource leaks in C, Objective-C and Java. In general, resources\nare entities such as files, sockets, connections, etc, that need to be closed\nafter being used."}),"\n",(0,r.jsx)(n.h3,{id:"resource-leak-in-c",children:"Resource leak in C"}),"\n",(0,r.jsx)(n.p,{children:"This is an example of a resource leak in C code:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-c",children:'-(void) resource_leak_bug {\n FILE *fp;\n fp=fopen("c:\\\\test.txt", "r"); // file opened and not closed.\n}\n'})}),"\n",(0,r.jsx)(n.h3,{id:"resource-leak-in-java",children:"Resource leak in Java"}),"\n",(0,r.jsx)(n.p,{children:"For the remaining of this section, we will consider examples of resource leaks\nin Java code."}),"\n",(0,r.jsxs)(n.p,{children:["TIP: A common source of bugs is ",(0,r.jsx)("b",{children:"exceptions skipping past close()\nstatements"}),". That is the first thing to look for if INFER reports a potential\nresource leak."]}),"\n",(0,r.jsx)(n.h3,{id:"basics-and-standard-idiom",children:"Basics and Standard Idiom"}),"\n",(0,r.jsxs)(n.p,{children:["Some objects in Java, the ",(0,r.jsx)("i",{children:"resources"}),", are supposed to be closed when you\nstop using them, and failure to close is a ",(0,r.jsx)("i",{children:"resource leak"}),". Resources\ninclude input streams, output streams, readers, writers, sockets, http\nconnections, cursors, and json parsers."]}),"\n",(0,r.jsx)(n.p,{children:"The standard idiom is"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:" // Standard idiom\n Allocate resource\n try {\n do some stuff\n } finally {\n close resource\n }\n"})}),"\n",(0,r.jsx)(n.p,{children:"or more for example,"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:' // Standard Idiom\n public static void foo () throws IOException{\n FileOutputStream fos = new FileOutputStream(new File("whatever.txt"));\n try {\n fos.write(7);\n } finally {\n fos.close();\n }\n }\n'})}),"\n",(0,r.jsx)(n.p,{children:"and you should use the standard idiom for the most part, when you don't want to\nreturn the resource to the surrounding context."}),"\n",(0,r.jsx)(n.p,{children:"Sometimes people just leave out close(), and that is a bug, but more typically\nexceptional paths are the root of the problem, as in"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:' // leak because of exception\n public static void foo () throws IOException {\n FileOutputStream fos = new FileOutputStream(new File("whatever.txt"));\n fos.write(7); //DOH! What if exception?\n fos.close();\n }\n'})}),"\n",(0,r.jsx)(n.p,{children:"where an exception in fos.write will cause execution to skip past the close()\nstatement."}),"\n",(0,r.jsx)(n.h4,{id:"multiple-resources-bugs",children:"Multiple Resources Bugs"}),"\n",(0,r.jsx)(n.p,{children:"We can deal with multiple resources correctly and simply just by nesting the\nstandard idiom."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:' // Two Resources nested\n public static void foo() throws IOException {\n FileInputStream fis = new FileInputStream(new File("whatever.txt"));\n try {\n FileOutputStream fos = new FileOutputStream(new File("everwhat.txt"));\n try {\n fos.write(fis.read());\n } finally {\n fos.close();\n }\n } finally {\n fis.close();\n }\n }\n'})}),"\n",(0,r.jsx)(n.p,{children:"Bugs often occur when using multiple resources in other ways because of\nexceptions in close() methods. For example,"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:' // Classic Two Resources Bug\n public static void foo() throws IOException {\n FileInputStream fis = null;\n FileOutputStream fos = null;\n try {\n fis = new FileInputStream(new File("whatever.txt"));\n fos = new FileOutputStream(new File("everwhat.txt"));\n fos.write(fis.read());\n } finally {\n if (fis!=null) fis.close();\n if (fos!=null) fos.close();\n }\n }\n'})}),"\n",(0,r.jsx)(n.p,{children:"Here, if there is an exception in the call to fis.close() execution will skip\npast fos.close(); a leak."}),"\n",(0,r.jsx)(n.p,{children:"Another way, besides the standard idiom, to deal with this problem is to swallow\nexceptions."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:' // Two Resources Fix 1\n public static void foo() throws IOException {\n FileInputStream fis = null;\n FileOutputStream fos = null;\n try {\n fis = new FileInputStream(new File("whatever.txt"));\n fos = new FileOutputStream(new File("everwhat.txt"));\n fos.write(fis.read());\n } finally {\n try {\n if (fis!=null) fis.close();\n } catch (Exception e) {}; // Exception swallowing\n if (fos!=null) fos.close();\n }\n }\n'})}),"\n",(0,r.jsxs)(n.p,{children:["You can also swallow the exception on the output stream. Some people prefer not\nto swallow output stream exceptions, and also flush before closing.\n",(0,r.jsx)(n.a,{href:"http://code.google.com/p/guava-libraries/issues/detail?id=1118",children:"http://code.google.com/p/guava-libraries/issues/detail?id=1118"})]}),"\n",(0,r.jsx)(n.p,{children:"Notice that the nested standard idiom does not need the checks for null, which\nare in there in this case to protect against the case when one of the\nallocations throws an exception, in which case one would get a\nNullPointerException."}),"\n",(0,r.jsx)(n.h3,{id:"nested_allocations",children:"Nested_Allocations"}),"\n",(0,r.jsx)(n.p,{children:"When a resource allocation is included as an argument to a constructor, if the\nconstructor fails it can leave an unreachable resource that no one can close."}),"\n",(0,r.jsx)(n.p,{children:"For example gzipOutputStream = new GZIPOutputStream(new FileOutputStream(out));\nis bad in case the outer constructor, GZIPOutputStream, throws an exception. In\nthat case, no one will have a hold of the FileOutputStream and so no one will be\nable to close it."}),"\n",(0,r.jsx)(n.p,{children:"In such a case you need to move the allocation the FileOutputStream out of the\nnested position and name it, so you are able to close if anything goes wrong\nduring execution of the GZIPOutputStream constructor."}),"\n",(0,r.jsx)(n.p,{children:"Here are resources that can throw exceptions i their constructor(s)."}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"ObjectInputStream , ObjectOutputStream, PipedInputStream, PipedOutputStream,\nPipedReader, PipedWriter, JarInputStream, JarOutputStream, GZIPInputStream,\nGZIPOutputStream , ZipFile all throw IOException"}),"\n",(0,r.jsx)(n.li,{children:"PrintStream throws UnsupportedEncodingException"}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"The constructors for FileInputStream, FileOutputStream and RandomAccessFile\nthrow FileNotFoundException, but these cases are not problematic in the sense\nthat their arguments are not resources and so they do not cause the nested\nresource leak."}),"\n",(0,r.jsx)(n.h3,{id:"allocation-of-jsonparser-and-cursor-resources",children:"Allocation of JSonParser and Cursor resources"}),"\n",(0,r.jsx)(n.p,{children:'Some resources are created inside libraries instead of by "new".'}),"\n",(0,r.jsx)(n.p,{children:"Cursor is an interface, the actual resources are something like SQLiteCursor.\nSo, every time you call a function that returns a Cursor object, there is an\nallocation."}),"\n",(0,r.jsx)(n.p,{children:"For instance, in the functions from SQLiteDatabase query(\u2026) and rawQuery(\u2026)\nallocate a cursor resource. For SQLiteQueryBuilder, ContentProviderClient,\nContentResolver. MediaStore and DownloadManager it is only query(\u2026) Cursor\nobjects cursor created by these functions need to be closed (i.e.,\ncursor.close())."}),"\n",(0,r.jsx)(n.p,{children:"Similarly, JsonParser is an abstract class, and create a resource in functions\nfrom the class JsonFactory createParser(byte[] data) createParser(byte[] data,\nint offset, int len) createParser(String content) createParser(URL url)\ncreateParser(File f) JsonParser objects js created by these functions need to be\nclosed (jp.close()). On the other hand . JasonParsers gotten from\ncreateParser(InputStream in) and createParser(Reader r) give you JsonParsers\nthat don\u2019t need to be closed. This is because they receive the resource from\nsomewhere that will maintain the responsibility to close it."}),"\n",(0,r.jsx)(n.h3,{id:"escaping-resources-and-exceptions",children:"Escaping resources and exceptions"}),"\n",(0,r.jsx)(n.p,{children:"Sometimes you want to return a resource to the outside, in which case you should\nnot close it, but you still need to be careful of exceptions in case control\nskips past the return leaving no one to close. Here is a simple example of a\npositive use of escaping resources."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:" // An escaping resource, shouldn't close\n public BugReportAttachment createAttachment(File reportDirectory, String fileName)\n throws FileNotFoundException {\n File file = new File(reportDirectory, fileName);\n OutputStream stream = new FileOutputStream(file);\n return new BugReportAttachment(Uri.fromFile(file), stream);\n }\n"})}),"\n",(0,r.jsxs)(n.p,{children:["In this case it is intended that an object that wraps ",(0,r.jsx)(n.code,{children:"stream"})," is passed to the\ncaller of ",(0,r.jsx)(n.code,{children:"createAttachment"}),". You should certainly not close stream here,\nbecause it is being passed to the outside."]}),"\n",(0,r.jsx)(n.p,{children:"But for escaping resources like this you still need to be careful of exceptions.\nFor example, in"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:" // An escaping resource, and a leak\n public BugReportAttachment createAttachment(File reportDirectory, String fileName)\n throws FileNotFoundException {\n File file = new File(reportDirectory, fileName);\n OutputStream stream = new FileOutputStream(file);\n stream.write(7);\n return new BugReportAttachment(Uri.fromFile(file), stream);\n }\n"})}),"\n",(0,r.jsx)(n.p,{children:"if stream.write(7) throws an exception, then no one will have a hold of stream,\nand no one will be able to close it; a leak."}),"\n",(0,r.jsx)(n.h3,{id:"java-7s-try-with-resources",children:"Java 7's try-with-resources"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"(For use with Java 7 only)"})}),"\n",(0,r.jsx)(n.p,{children:"Clearly, accounting for the ramifications of all the exceptional cases is\ncomplicated, and there is a better way in Java 7."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:' // Two Resources Fix 2; via try-with-resources\n public static void foo() throws IOException {\n try (\n FileInputStream fis = new FileInputStream(new File("whatever.txt"));\n FileOutputStream fos = new FileOutputStream(new File("everwhat.txt"))\n ) {\n fos.write(fis.read());\n }\n }\n'})}),"\n",(0,r.jsx)(n.p,{children:"All the complicated exceptional cases above are (apparently) covered by this\nconstruct, and the result is much simpler."}),"\n",(0,r.jsx)(n.p,{children:"So, if you are trying to fix a potential leak in code with multiples resources\nyou can go ahead and try to understand whether the potential leak is real. Or,\nif the code is complex and it is hard to figure out, it would be perfectly\nlegitimate to simply convert the code over to try-with-resources if you have\naccess to Java 7, so as to save yourself some brain-cycles. You will also end up\nwith cleaner code."}),"\n",(0,r.jsxs)(n.p,{children:["If try-with-resources is so great you should ",(0,r.jsx)("i",{children:"always"}),' use it. But you\nshouldn\'t\u2026 Try-with-resources gives resources static scoping, and works via a\nstack discipline. Sometimes, you want a resource to persist beyond scope, as in\nthe escaping example above. In an escaping example maybe you could refactor lots\nof code so that try-with-resources applies, and maybe you cannot in a sensible\nway. This just illustrates that, though you might hear people say that\ntry-with-resources "solves" the resource problem, it does not. It is very\nuseful, but you cannot use it blindly when you see a resource-allocation site.']}),"\n",(0,r.jsx)(n.h2,{id:"retain_cycle",children:"RETAIN_CYCLE"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#resource-leak",children:"Resource leak"}),'. Reported as "Retain Cycle" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"A retain cycle is a situation when object A retains object B, and object B\nretains object A at the same time. Here is an example:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objectivec",children:"@class Child;\n@interface Parent : NSObject {\n Child *child; // Instance variables are implicitly __strong\n}\n@end\n@interface Child : NSObject {\n Parent *parent;\n}\n@end\n"})}),"\n",(0,r.jsx)(n.p,{children:'You can fix a retain cycle in ARC by using __weak variables or weak properties\nfor your "back links", i.e. links to direct or indirect parents in an object\nhierarchy:'}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objectivec",children:"@class Child;\n@interface Parent : NSObject {\n Child *child;\n}\n@end\n@interface Child : NSObject {\n __weak Parent *parent;\n}\n@end\n"})}),"\n",(0,r.jsx)(n.h2,{id:"retain_cycle_no_weak_info",children:"RETAIN_CYCLE_NO_WEAK_INFO"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#resource-leak",children:"Resource leak"}),'. Reported as "Retain Cycle No Weak Info" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"A retain cycle is a situation when object A retains object B, and object B\nretains object A at the same time. Here is an example:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objectivec",children:"@class Child;\n@interface Parent : NSObject {\n Child *child; // Instance variables are implicitly __strong\n}\n@end\n@interface Child : NSObject {\n Parent *parent;\n}\n@end\n"})}),"\n",(0,r.jsx)(n.p,{children:'You can fix a retain cycle in ARC by using __weak variables or weak properties\nfor your "back links", i.e. links to direct or indirect parents in an object\nhierarchy:'}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objectivec",children:"@class Child;\n@interface Parent : NSObject {\n Child *child;\n}\n@end\n@interface Child : NSObject {\n __weak Parent *parent;\n}\n@end\n"})}),"\n",(0,r.jsx)(n.h2,{id:"scope_leakage",children:"SCOPE_LEAKAGE"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#sensitive-data-flow",children:"Sensitive data flow"}),'. Reported as "Scope Leakage" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-scope-leakage",children:"scope-leakage"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:'This issue type indicates that a class with scope annotation A stores a field\nwith whose (dynamic) type (or one of its super types) is annotated with scope\nB such that a scope nesting restriction is violated. By "stores", we mean\neither directly or transitively.'}),"\n",(0,r.jsx)(n.p,{children:"A configuration is used to list the set of scopes and the must-not-hold relation."}),"\n",(0,r.jsx)(n.p,{children:"In the following Java example, the set of scopes is Outer and Inner, and the must-not-hold\nrelation is simply {(Outer, Inner)}:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"@ScopeType(value = Outer.class)\nclass ClassOfOuterScope {\n final ClassOfInner c = new ClassOfInner(); // <-- warn here that ClassOfInner would leak.\n}\n\n@ScopeType(value = Inner.class)\nclass ClassOfInner {}\n"})}),"\n",(0,r.jsx)(n.p,{children:"Here is a more detailed description of the analysis."}),"\n",(0,r.jsx)(n.p,{children:'This analysis operates over Java bytecode. It assumes that types (classes, interfaces, enums,\netc.) may be annotated with so-called scope annotations. The analysis is parameterized by a set\nof scopes and a "must-not-hold" relation over pairs of scopes, which it reads from a\nconfiguration file.'}),"\n",(0,r.jsx)(n.p,{children:'The analysis aims to detect violations of the following property: if there exist a path of\nfields from object OA to object OB and the type of OA (or one of its super-types) is annotated\nwith scope SA and the type of OB (or one of its super-types) is annotated with scope SB then\nmust-not-hold(SA, SB) must be false. Intuitively, the given objects have different scopes that\nshould not be nested, for example, different intended lifetimes, and a forbidden path from OA to\nOB results in OB "leaking" out of the scope SA.'}),"\n",(0,r.jsx)(n.p,{children:'The implementation reads a configuration to determine a list of (scope) "generators" for each\ntype of scope and a scope class for each type of scope. A generator for a scope type SA is given\nby the name of a class and a list of methods where it is understood that any of the methods\nlisted for the given class returns an object that is known to have scope SA. (This can be seen\nas a form of lightweight modeling.) A scope class is the name of the class that represents a\ngiven scope.'}),"\n",(0,r.jsx)(n.h2,{id:"self_in_block_passed_to_init",children:"SELF_IN_BLOCK_PASSED_TO_INIT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#resource-leak",children:"Resource leak"}),'. Reported as "Self In Block Passed To Init" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-self-in-block",children:"self-in-block"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This check flags when ",(0,r.jsx)(n.code,{children:"self"})," is captured in a block that is passed to an initialiser method. That\ncould cause retain cycles if the initialiser code retains the block."]}),"\n",(0,r.jsx)(n.p,{children:"Example:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objectivec",children:" [obj initWithHandler:^() {\n [self foo];\n ...\n }];\n"})}),"\n",(0,r.jsxs)(n.p,{children:["Instead it's better to use the ",(0,r.jsx)(n.code,{children:"weakSelf"}),"/",(0,r.jsx)(n.code,{children:"strongSelf"})," pattern."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objectivec",children:" __weak __typeof(self) weakSelf = self;\n [obj initWithHandler:^() {\n __strong __typeof(weakSelf) strongSelf = weakSelf;\n if (strongSelf) {\n [strongSelf foo];\n }\n ...\n }];\n"})}),"\n",(0,r.jsx)(n.h2,{id:"sensitive_data_flow",children:"SENSITIVE_DATA_FLOW"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#sensitive-data-flow",children:"Sensitive data flow"}),'. Reported as "Sensitive Data Flow" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"A flow of sensitive data was detected from a source."}),"\n",(0,r.jsx)(n.h2,{id:"stack_variable_address_escape",children:"STACK_VARIABLE_ADDRESS_ESCAPE"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#memory-error",children:"Memory error"}),'. Reported as "Stack Variable Address Escape" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"Reported when an address pointing into the stack of the current\nfunction will escape to its calling context. Such addresses will\nbecome invalid by the time the function actually returns so are\npotentially dangerous."}),"\n",(0,r.jsx)(n.p,{children:"For example, directly returning a pointer to a local variable:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-C",children:'int* foo() {\n int x = 42;\n return &x; // <-- warn here that "&x" will escape\n}\n'})}),"\n",(0,r.jsx)(n.h2,{id:"starvation",children:"STARVATION"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "UI Thread Starvation" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-starvation",children:"starvation"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"This error is reported in Java, and specifically on Android. These reports are\ntriggered when a method that runs on the UI thread may block, thus potentially\nleading to an Application Not Responding error."}),"\n",(0,r.jsx)(n.p,{children:"Infer considers a method as running on the UI thread whenever:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["The method, one of its overrides, its class, or an ancestral class, is\nannotated with ",(0,r.jsx)(n.code,{children:"@UiThread"}),"."]}),"\n",(0,r.jsxs)(n.li,{children:["The method, or one of its overrides is annotated with ",(0,r.jsx)(n.code,{children:"@OnEvent"}),", ",(0,r.jsx)(n.code,{children:"@OnClick"}),",\netc."]}),"\n",(0,r.jsxs)(n.li,{children:["The method or its callees call a ",(0,r.jsx)(n.code,{children:"Litho.ThreadUtils"})," method such as\n",(0,r.jsx)(n.code,{children:"assertMainThread"}),"."]}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"The issue is reported when a method deemed to run on the UI thread"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Makes a method call which may block."}),"\n",(0,r.jsx)(n.li,{children:"Takes a lock, and another thread takes the same lock, and before releasing it,\nmakes a call that may block."}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"Calls that may block are considered:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Certain I/O calls."}),"\n",(0,r.jsxs)(n.li,{children:["Two way ",(0,r.jsx)(n.code,{children:"Binder.transact"})," calls."]}),"\n",(0,r.jsx)(n.li,{children:"Certain OS calls."}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"Future"})," or ",(0,r.jsx)(n.code,{children:"AsyncTask"})," calls to ",(0,r.jsx)(n.code,{children:"get"})," without timeouts, or with too large\ntimeouts."]}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:["To suppress starvation reports in a method ",(0,r.jsx)(n.code,{children:"m()"})," use the\n",(0,r.jsx)(n.code,{children:'@SuppressLint("STARVATION")'})," annotation, as follows:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:' import android.annotation.SuppressLint;\n\n @SuppressLint("STARVATION")\n public void m() {\n ...\n }\n'})}),"\n",(0,r.jsxs)(n.p,{children:["To signal to Infer that a method does not perform any blocking calls, despite\nappearences, you can use the ",(0,r.jsx)(n.code,{children:"@NonBlocking"})," annotation:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:" import com.facebook.infer.annotation.NonBlocking;\n\n @NonBlocking\n public void m() {\n ...\n }\n"})}),"\n",(0,r.jsxs)(n.p,{children:["This instructs Infer to filter out any potentially blocking calls in ",(0,r.jsx)(n.code,{children:"m()"}),"\n(also, transitively), and thus any other method can expect no starvation reports\ndue to a call to ",(0,r.jsx)(n.code,{children:"m()"}),". You will need to set up your class path appropriately to\ninclude the JAR files in ",(0,r.jsx)(n.code,{children:"infer/annotations"})," for this annotation to work."]}),"\n",(0,r.jsx)(n.h2,{id:"static_constructor_stall",children:"STATIC_CONSTRUCTOR_STALL"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#concurrency",children:"Concurrency"}),'. Reported as "Static Constructor Stall" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-static-constructor-stall-checker",children:"static-constructor-stall-checker"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"Calling certain methods, for instance dispatch_once, during the static initialization of objects is risky. It could cause deadlocks, because other objects might not have been initialized yet."}),"\n",(0,r.jsx)(n.h2,{id:"static_initialization_order_fiasco",children:"STATIC_INITIALIZATION_ORDER_FIASCO"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#memory-error",children:"Memory error"}),'. Reported as "Static Initialization Order Fiasco" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-siof",children:"siof"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This error is reported in C++. It fires when the initialization of a static\nvariable ",(0,r.jsx)(n.code,{children:"A"}),", accesses a static variable ",(0,r.jsx)(n.code,{children:"B"})," from another translation unit\n(usually another ",(0,r.jsx)(n.code,{children:".cpp"})," file). There are no guarantees whether ",(0,r.jsx)(n.code,{children:"B"})," has been\nalready initialized or not at that point."]}),"\n",(0,r.jsxs)(n.p,{children:["For more technical definition and techniques to avoid/remediate, see the\n",(0,r.jsx)(n.a,{href:"https://isocpp.org/wiki/faq/ctors#static-init-order",children:"FAQ"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"strict_mode_violation",children:"STRICT_MODE_VIOLATION"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#perf-regression",children:"Perf regression"}),'. Reported as "Strict Mode Violation" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-starvation",children:"starvation"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["Android has a feature called\n",(0,r.jsx)(n.a,{href:"https://developer.android.com/reference/android/os/StrictMode",children:"strict mode"}),",\nwhich if enabled, will flag the occasions where the main thread makes a call\nthat results in disk I/O, waiting on a network socket, etc. The analysis\ncatching starvation errors and deadlocks (the ",(0,r.jsx)(n.code,{children:"--starvation"})," analysis) has the\nability to statically detect such violations."]}),"\n",(0,r.jsxs)(n.p,{children:["To suppress this warning, it's enough to annotate the offending method with\n",(0,r.jsx)(n.code,{children:'@SuppressLint("STRICT_MODE_VIOLATION")'}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"strong_self_not_checked",children:"STRONG_SELF_NOT_CHECKED"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#memory-error",children:"Memory error"}),'. Reported as "StrongSelf Not Checked" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-self-in-block",children:"self-in-block"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This checks reports a potential issue when a block captures ",(0,r.jsx)(n.code,{children:"weakSelf"})," (a weak pointer to ",(0,r.jsx)(n.code,{children:"self"}),"),\nthen one assigns this pointer to a local variable ",(0,r.jsx)(n.code,{children:"strongSelf"})," inside the block and uses this variable\nwithout checking first whether it is ",(0,r.jsx)(n.code,{children:"nil"}),". The problem here is that the weak pointer could be ",(0,r.jsx)(n.code,{children:"nil"})," at\nthe time when the block is executed. So, the correct usage is to first check whether ",(0,r.jsx)(n.code,{children:"strongSelf"})," is a valid\npointer, and then use it."]}),"\n",(0,r.jsx)(n.p,{children:"Example:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objectivec",children:"__weak __typeof(self) weakSelf = self;\n int (^my_block)() = ^() {\n __strong __typeof(weakSelf) strongSelf = weakSelf;\n int y = strongSelf->x;\n ...\n"})}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"Action:"}),"\nAdd a check for ",(0,r.jsx)(n.code,{children:"nil"}),":"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objectivec",children:"__weak __typeof(self) weakSelf = self;\n int (^my_block)() = ^() {\n __strong __typeof(weakSelf) strongSelf = weakSelf;\n if (strongSelf) {\n int y = strongSelf->x;\n ...\n }\n"})}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.em,{children:"Limitations:"})," To keep this check simple and intra-procedural, we rely on names to find ",(0,r.jsx)(n.code,{children:"weakSelf"}),':\nwe assume that any captured weak pointer whose name contains "self" is a weak reference to ',(0,r.jsx)(n.code,{children:"self"}),".\nIn contrast, ",(0,r.jsx)(n.code,{children:"strongSelf"})," is a local variable to the block, so the check supports any name given to\na local strong pointer that has been assigned ",(0,r.jsx)(n.code,{children:"weakSelf"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"taint_error",children:"TAINT_ERROR"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#sensitive-data-flow",children:"Sensitive data flow"}),'. Reported as "Taint Error" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"A taint flow was detected from a source to a sink"}),"\n",(0,r.jsx)(n.h2,{id:"thread_safety_violation",children:"THREAD_SAFETY_VIOLATION"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#concurrency",children:"Concurrency"}),'. Reported as "Thread Safety Violation" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-racerd",children:"racerd"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This warning indicates a potential data race in Java. The analyser is called\nRacerD and this section gives brief but a mostly complete description of its\nfeatures. See the ",(0,r.jsx)(n.a,{href:"/docs/next/checker-racerd",children:"RacerD page"})," for more in-depth information and\nexamples."]}),"\n",(0,r.jsx)(n.h3,{id:"thread-safety-what-is-a-data-race",children:"Thread-safety: What is a data race"}),"\n",(0,r.jsx)(n.p,{children:"Here a data race is a pair of accesses to the same member field such that:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"at least one is a write, and,"}),"\n",(0,r.jsx)(n.li,{children:"at least one occurs without any lock synchronization, and,"}),"\n",(0,r.jsx)(n.li,{children:"the two accesses occur on threads (if known) which can run in parallel."}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"thread-safety-potential-fixes",children:"Thread-safety: Potential fixes"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["Synchronizing the accesses (using the ",(0,r.jsx)(n.code,{children:"synchronized"})," keyword, thread-exclusion\nsuch as atomic objects, ",(0,r.jsx)(n.code,{children:"volatile"})," etc)."]}),"\n",(0,r.jsx)(n.li,{children:"Making an offending method private -- this will exclude it from being checked\nat the top level, though it will be checked if called by a public method which\nmay itself, e.g., hold a lock when calling it."}),"\n",(0,r.jsxs)(n.li,{children:["Putting the two accesses on the same thread, e.g., by using ",(0,r.jsx)(n.code,{children:"@MainThread"})," or\n",(0,r.jsx)(n.code,{children:"@ThreadConfined"}),"."]}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"thread-safety-conditions-checked-before-reporting",children:"Thread-safety: Conditions checked before reporting"}),"\n",(0,r.jsxs)(n.p,{children:["The class and method are not marked ",(0,r.jsx)(n.code,{children:"@ThreadSafe(enableChecks = false)"}),", and,"]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["The method is declared ",(0,r.jsx)(n.code,{children:"synchronized"}),", or employs (non-transitively) locking,\nor,"]}),"\n",(0,r.jsxs)(n.li,{children:["The class is not marked ",(0,r.jsx)(n.code,{children:"@NotThreadSafe"}),", and,","\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["The class/method is marked ",(0,r.jsx)(n.code,{children:"@ThreadSafe,"})," or one of the configured synonyms\nin ",(0,r.jsx)(n.code,{children:".inferconfig"}),", or,"]}),"\n",(0,r.jsx)(n.li,{children:"A parent class, or an override method are marked with the above annotations."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:["NB currently RacerD ",(0,r.jsxs)(n.strong,{children:["does not take into account ",(0,r.jsx)(n.code,{children:"@GuardedBy"})]}),"."]}),"\n",(0,r.jsx)(n.h3,{id:"thread-safety-thread-annotations-recognized-by-racerd",children:"Thread-safety: Thread annotations recognized by RacerD"}),"\n",(0,r.jsxs)(n.p,{children:["These class and method annotations imply the method is on the main thread:\n",(0,r.jsx)(n.code,{children:"@MainThread"}),", ",(0,r.jsx)(n.code,{children:"@UiThread"})]}),"\n",(0,r.jsxs)(n.p,{children:["These method annotations imply the method is on the main thread: ",(0,r.jsx)(n.code,{children:"@OnBind"}),",\n",(0,r.jsx)(n.code,{children:"@OnEvent"}),", ",(0,r.jsx)(n.code,{children:"@OnMount"}),", ",(0,r.jsx)(n.code,{children:"@OnUnbind"}),", ",(0,r.jsx)(n.code,{children:"@OnUnmount"})]}),"\n",(0,r.jsx)(n.p,{children:"Both classes of annotations work through the inheritance tree (i.e. if a parent\nclass or method is marked with one of these annotations, so is the child class /\nmethod override)."}),"\n",(0,r.jsxs)(n.p,{children:["In addition to these, RacerD recognizes many lifecycle methods as necessarily\nrunning on the main thread, eg ",(0,r.jsx)(n.code,{children:"Fragment.onCreate"})," etc."]}),"\n",(0,r.jsxs)(n.p,{children:["Finally, the thread status of being on the main thread propagates backwards\nthrough the call graph (ie if ",(0,r.jsx)(n.code,{children:"foo"})," calls ",(0,r.jsx)(n.code,{children:"bar"})," and ",(0,r.jsx)(n.code,{children:"bar"})," is marked ",(0,r.jsx)(n.code,{children:"@UiThtread"}),"\nthen ",(0,r.jsx)(n.code,{children:"foo"})," is automatically considered on the main thread too). Calling\n",(0,r.jsx)(n.code,{children:"assertMainThread"}),", ",(0,r.jsx)(n.code,{children:"assertOnUiThread"}),", ",(0,r.jsx)(n.code,{children:"checkOnMainThread"})," has the same effect."]}),"\n",(0,r.jsxs)(n.p,{children:["NB RacerD currently ",(0,r.jsxs)(n.strong,{children:["does not recognize ",(0,r.jsx)(n.code,{children:"@WorkerThread"}),", ",(0,r.jsx)(n.code,{children:"@BinderThread"})," or\n",(0,r.jsx)(n.code,{children:"@AnyThread"})]}),"."]}),"\n",(0,r.jsx)(n.h3,{id:"thread-safety-other-annotations-and-what-they-do",children:"Thread-safety: Other annotations and what they do"}),"\n",(0,r.jsxs)(n.p,{children:["These annotations can be found at ",(0,r.jsx)(n.code,{children:"com.facebook.infer.annotation.*"}),"."]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"@Functional"})," This is a method annotation indicating the method always returns\nthe same value. When a method ",(0,r.jsx)(n.code,{children:"foo"})," is annotated ",(0,r.jsx)(n.code,{children:"@Functional"}),", RacerD will\nignore any writes of the return value of ",(0,r.jsx)(n.code,{children:"foo"}),". For example, in\n",(0,r.jsx)(n.code,{children:"this.x = foo()"}),", the write to ",(0,r.jsx)(n.code,{children:"this.x"})," is ignored. The reasoning is that if\nthe method returns the same value whenever it's called, any data race on\n",(0,r.jsx)(n.code,{children:"this.x"})," is benign, if that is the only write."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"@ThreadConfined"})," This is a class/method/field annotation which takes a single\nparameter which can be ",(0,r.jsx)(n.code,{children:"UI"}),", ",(0,r.jsx)(n.code,{children:"ANY"})," or a user chosen string. It indicates to\nRacerD a thread identifier for the class/method/field. Thus,\n",(0,r.jsx)(n.code,{children:"@ThreadConfined(UI)"})," is equivalent to ",(0,r.jsx)(n.code,{children:"@UiThread"}),", and ",(0,r.jsx)(n.code,{children:"@ThreadConfined(ANY)"}),"\nis equivalent to not having the annotation at all, for classes and methods.\nWhen this annotation is applied to a field it instructs Infer to assume\n(without checking) that all accesses to that field are made on the same thread\n(and can, therefore, not race by definition). The intention is that RacerD\nuses that to detect exclusion between accesses occurring on the same thread.\nHowever, only the UI thread is supported at this time, and any user provided\nvalue is considered equal to ",(0,r.jsx)(n.code,{children:"UI"}),"."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"@VisibleForTesting"})," A method annotation making Infer consider the method as\neffectively ",(0,r.jsx)(n.code,{children:"private"}),". This means it will not be checked for races against\nother non-private methods of the class, but only if called by one."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"@ReturnsOwnership"})," A method annotation indicating that the method returns a\nfreshly owned object. Accesses to the returned value will not be considered\nfor data races, as the object is in-effect unique and not accessible yet from\nother threads. The main utility of this annotation is in interfaces, where\nInfer cannot look up the implementation and decide for itself."]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"topl_error",children:"TOPL_ERROR"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#user-defined-property",children:"User defined property"}),'. Reported as "Topl Error" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-topl",children:"topl"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"A violation of a Topl property (user-specified).\nThere is an execution path in the code that drives a Topl property from a start state to an error state."}),"\n",(0,r.jsx)(n.p,{children:"This indicates that the code has a user-defined undesired behavior."}),"\n",(0,r.jsxs)(n.p,{children:["See ",(0,r.jsx)(n.a,{href:"/docs/next/checker-topl#what-is-it",children:"Topl"})," for an example"]}),"\n",(0,r.jsx)(n.h2,{id:"topl_error_latent",children:"TOPL_ERROR_LATENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#user-defined-property",children:"User defined property"}),'. Reported as "Topl Error Latent" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-topl",children:"topl"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A latent ",(0,r.jsx)(n.a,{href:"#topl_error",children:"TOPL_ERROR"}),". See the ",(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse#latent-issues",children:"documentation on Pulse latent issues"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"use_after_delete",children:"USE_AFTER_DELETE"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#memory-error",children:"Memory error"}),'. Reported as "Use After Delete" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["An address that was invalidated by a call to ",(0,r.jsx)(n.code,{children:"delete"})," in C++ is dereferenced."]}),"\n",(0,r.jsx)(n.h2,{id:"use_after_delete_latent",children:"USE_AFTER_DELETE_LATENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#memory-error",children:"Memory error"}),'. Reported as "Use After Delete Latent" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A latent ",(0,r.jsx)(n.a,{href:"#use_after_delete",children:"USE_AFTER_DELETE"}),". See the ",(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse#latent-issues",children:"documentation on Pulse latent issues"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"use_after_free",children:"USE_AFTER_FREE"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#memory-error",children:"Memory error"}),'. Reported as "Use After Free" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["An address that was invalidated by a call to ",(0,r.jsx)(n.code,{children:"free"})," in C is dereferenced."]}),"\n",(0,r.jsx)(n.h2,{id:"use_after_free_latent",children:"USE_AFTER_FREE_LATENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#memory-error",children:"Memory error"}),'. Reported as "Use After Free Latent" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A latent ",(0,r.jsx)(n.a,{href:"#use_after_free",children:"USE_AFTER_FREE"}),". See the ",(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse#latent-issues",children:"documentation on Pulse latent issues"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"use_after_lifetime",children:"USE_AFTER_LIFETIME"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#memory-error",children:"Memory error"}),'. Reported as "Use After Lifetime" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"The lifetime of an object has ended but that object is being\naccessed. For example, the address of a variable holding a C++ object\nis accessed after the variable has gone out of scope:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-cpp",children:"void foo() {\n X* p;\n { // new scope\n X x = X();\n p = &x;\n } // x has gone out of scope\n p->method(); // ERROR: you should not access *p after x has gone out of scope\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"use_after_lifetime_latent",children:"USE_AFTER_LIFETIME_LATENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#memory-error",children:"Memory error"}),'. Reported as "Use After Lifetime Latent" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A latent ",(0,r.jsx)(n.a,{href:"#use_after_lifetime",children:"USE_AFTER_LIFETIME"}),". See the ",(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse#latent-issues",children:"documentation on Pulse latent issues"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"vector_invalidation",children:"VECTOR_INVALIDATION"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#memory-error",children:"Memory error"}),'. Reported as "Vector Invalidation" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["An address pointing into a C++ ",(0,r.jsx)(n.code,{children:"std::vector"})," might have become\ninvalid. This can happen when an address is taken into a vector, then\nthe vector is mutated in a way that might invalidate the address, for\nexample by adding elements to the vector, which might trigger a\nre-allocation of the entire vector contents (thereby invalidating the\npointers into the previous location of the contents)."]}),"\n",(0,r.jsx)(n.p,{children:"For example:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-cpp",children:'void deref_vector_element_after_push_back_bad(std::vector& vec) {\n int* elt = &vec[1];\n int* y = elt;\n vec.push_back(42); // if the array backing the vector was full already, this\n // will re-allocate it and copy the previous contents\n // into the new array, then delete the previous array\n std::cout << *y << "\\n"; // bad: y might be invalid\n}\n'})}),"\n",(0,r.jsx)(n.h2,{id:"vector_invalidation_latent",children:"VECTOR_INVALIDATION_LATENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#memory-error",children:"Memory error"}),'. Reported as "Vector Invalidation Latent" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A latent ",(0,r.jsx)(n.a,{href:"#vector_invalidation",children:"VECTOR_INVALIDATION"}),". See the ",(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse#latent-issues",children:"documentation on Pulse latent issues"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"weak_self_in_no_escape_block",children:"WEAK_SELF_IN_NO_ESCAPE_BLOCK"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Weak Self In No Escape Block" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-self-in-block",children:"self-in-block"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This check reports when ",(0,r.jsx)(n.code,{children:"weakSelf"})," (a weak pointer to ",(0,r.jsx)(n.code,{children:"self"}),') is used in\na block, and this block is passed to a "no escaping" method. This means that\nthe block passed to that method won\'t be leaving the current scope, this is\nmarked with the annotation ',(0,r.jsx)(n.code,{children:"NS_NOESCAPE"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:['The issue here is that, because the block is "no escaping", there is no need to use\n',(0,r.jsx)(n.code,{children:"weakSelf"})," and ",(0,r.jsx)(n.code,{children:"strongSelf"})," but we can just use ",(0,r.jsx)(n.code,{children:"self"}),". This has the advantage of\nnot needing to deal with the added complexity of weak pointers, and it simplifies the\ncode."]}),"\n",(0,r.jsx)(n.p,{children:"Example:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objectivec",children:" __weak __typeof(self) weakSelf = self;\n [self foo:^() { //foo's first parameter is annotates with `NS_NOESCAPE`\n [weakSelf bar];\n }];\n"})}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"Action"}),":"]}),"\n",(0,r.jsxs)(n.p,{children:["Replace ",(0,r.jsx)(n.code,{children:"weakSelf"})," with ",(0,r.jsx)(n.code,{children:"self"}),":"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objectivec",children:" [self foo:^() {\n [self bar];\n }];\n"})}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.em,{children:"Limitations:"})," To keep this check simple and intra-procedural, we rely on names to find ",(0,r.jsx)(n.code,{children:"weakSelf"}),':\nwe assume that any captured weak pointer whose name contains "self" is a weak reference to ',(0,r.jsx)(n.code,{children:"self"}),"."]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},8453:(e,n,s)=>{s.d(n,{R:()=>a,x:()=>l});var r=s(6540);const i={},t=r.createContext(i);function a(e){const n=r.useContext(t);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),r.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c359af60.87765c92.js b/assets/js/c359af60.87765c92.js new file mode 100644 index 00000000000..6b7908d2416 --- /dev/null +++ b/assets/js/c359af60.87765c92.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[2316],{28:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>t,metadata:()=>l,toc:()=>o});var r=s(4848),i=s(8453);const t={title:"List of all issue types"},a=void 0,l={id:"all-issue-types",title:"List of all issue types",description:"Here is an overview of the issue types currently reported by Infer.",source:"@site/docs/all-issue-types.md",sourceDirName:".",slug:"/all-issue-types",permalink:"/docs/next/all-issue-types",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"List of all issue types"},sidebar:"docs",previous:{title:"List of all categories of issue types",permalink:"/docs/next/all-categories"},next:{title:"Annotation Reachability",permalink:"/docs/next/checker-annotation-reachability"}},c={},o=[{value:"ARBITRARY_CODE_EXECUTION_UNDER_LOCK",id:"arbitrary_code_execution_under_lock",level:2},{value:"BAD_ARG",id:"bad_arg",level:2},{value:"BAD_ARG_LATENT",id:"bad_arg_latent",level:2},{value:"BAD_GENERATOR",id:"bad_generator",level:2},{value:"BAD_GENERATOR_LATENT",id:"bad_generator_latent",level:2},{value:"BAD_KEY",id:"bad_key",level:2},{value:"BAD_KEY_LATENT",id:"bad_key_latent",level:2},{value:"BAD_MAP",id:"bad_map",level:2},{value:"BAD_MAP_LATENT",id:"bad_map_latent",level:2},{value:"BAD_RECORD",id:"bad_record",level:2},{value:"BAD_RECORD_LATENT",id:"bad_record_latent",level:2},{value:"BAD_RETURN",id:"bad_return",level:2},{value:"BAD_RETURN_LATENT",id:"bad_return_latent",level:2},{value:"BIABDUCTION_MEMORY_LEAK",id:"biabduction_memory_leak",level:2},{value:"BIABDUCTION_RETAIN_CYCLE",id:"biabduction_retain_cycle",level:2},{value:"BLOCK_PARAMETER_NOT_NULL_CHECKED",id:"block_parameter_not_null_checked",level:2},{value:"BUFFER_OVERRUN_L1",id:"buffer_overrun_l1",level:2},{value:"BUFFER_OVERRUN_L2",id:"buffer_overrun_l2",level:2},{value:"BUFFER_OVERRUN_L3",id:"buffer_overrun_l3",level:2},{value:"BUFFER_OVERRUN_L4",id:"buffer_overrun_l4",level:2},{value:"BUFFER_OVERRUN_L5",id:"buffer_overrun_l5",level:2},{value:"BUFFER_OVERRUN_S2",id:"buffer_overrun_s2",level:2},{value:"BUFFER_OVERRUN_U5",id:"buffer_overrun_u5",level:2},{value:"CAPTURED_STRONG_SELF",id:"captured_strong_self",level:2},{value:"CHECKERS_ALLOCATES_MEMORY",id:"checkers_allocates_memory",level:2},{value:"CHECKERS_ANNOTATION_REACHABILITY_ERROR",id:"checkers_annotation_reachability_error",level:2},{value:"CHECKERS_CALLS_EXPENSIVE_METHOD",id:"checkers_calls_expensive_method",level:2},{value:"CHECKERS_EXPENSIVE_OVERRIDES_UNANNOTATED",id:"checkers_expensive_overrides_unannotated",level:2},{value:"CHECKERS_FRAGMENT_RETAINS_VIEW",id:"checkers_fragment_retains_view",level:2},{value:"COMPARED_TO_NULL_AND_DEREFERENCED",id:"compared_to_null_and_dereferenced",level:2},{value:"CONFIG_IMPACT",id:"config_impact",level:2},{value:"CONFIG_IMPACT_STRICT",id:"config_impact_strict",level:2},{value:"CONFIG_USAGE",id:"config_usage",level:2},{value:"CONSTANT_ADDRESS_DEREFERENCE",id:"constant_address_dereference",level:2},{value:"CONSTANT_ADDRESS_DEREFERENCE_LATENT",id:"constant_address_dereference_latent",level:2},{value:"CXX_REF_CAPTURED_IN_BLOCK",id:"cxx_ref_captured_in_block",level:2},{value:"CXX_STRING_CAPTURED_IN_BLOCK",id:"cxx_string_captured_in_block",level:2},{value:"DANGLING_POINTER_DEREFERENCE",id:"dangling_pointer_dereference",level:2},{value:"DATA_FLOW_TO_SINK",id:"data_flow_to_sink",level:2},{value:"DEADLOCK",id:"deadlock",level:2},{value:"DEAD_STORE",id:"dead_store",level:2},{value:"DIVIDE_BY_ZERO",id:"divide_by_zero",level:2},{value:"EMPTY_VECTOR_ACCESS",id:"empty_vector_access",level:2},{value:"EXECUTION_TIME_COMPLEXITY_INCREASE",id:"execution_time_complexity_increase",level:2},{value:"EXECUTION_TIME_COMPLEXITY_INCREASE_UI_THREAD",id:"execution_time_complexity_increase_ui_thread",level:2},{value:"EXECUTION_TIME_UNREACHABLE_AT_EXIT",id:"execution_time_unreachable_at_exit",level:2},{value:"EXPENSIVE_EXECUTION_TIME",id:"expensive_execution_time",level:2},{value:"EXPENSIVE_LOOP_INVARIANT_CALL",id:"expensive_loop_invariant_call",level:2},{value:"GUARDEDBY_VIOLATION",id:"guardedby_violation",level:2},{value:"IMPURE_FUNCTION",id:"impure_function",level:2},{value:"INEFFICIENT_KEYSET_ITERATOR",id:"inefficient_keyset_iterator",level:2},{value:"INFERBO_ALLOC_IS_BIG",id:"inferbo_alloc_is_big",level:2},{value:"INFERBO_ALLOC_IS_NEGATIVE",id:"inferbo_alloc_is_negative",level:2},{value:"INFERBO_ALLOC_IS_ZERO",id:"inferbo_alloc_is_zero",level:2},{value:"INFERBO_ALLOC_MAY_BE_BIG",id:"inferbo_alloc_may_be_big",level:2},{value:"INFERBO_ALLOC_MAY_BE_NEGATIVE",id:"inferbo_alloc_may_be_negative",level:2},{value:"INFINITE_EXECUTION_TIME",id:"infinite_execution_time",level:2},{value:"Example 1: T due to expressivity",id:"example-1-t-due-to-expressivity",level:3},{value:"Example 2: T due to unmodeled calls",id:"example-2-t-due-to-unmodeled-calls",level:3},{value:"Example 3: T due to calling another T-costed function",id:"example-3-t-due-to-calling-another-t-costed-function",level:3},{value:"INFINITE_RECURSION",id:"infinite_recursion",level:2},{value:"INTEGER_OVERFLOW_L1",id:"integer_overflow_l1",level:2},{value:"INTEGER_OVERFLOW_L2",id:"integer_overflow_l2",level:2},{value:"INTEGER_OVERFLOW_L5",id:"integer_overflow_l5",level:2},{value:"INTEGER_OVERFLOW_U5",id:"integer_overflow_u5",level:2},{value:"INTERFACE_NOT_THREAD_SAFE",id:"interface_not_thread_safe",level:2},{value:"INVALID_SIL",id:"invalid_sil",level:2},{value:"INVARIANT_CALL",id:"invariant_call",level:2},{value:"IPC_ON_UI_THREAD",id:"ipc_on_ui_thread",level:2},{value:"LAB_RESOURCE_LEAK",id:"lab_resource_leak",level:2},{value:"LINEAGE_FLOW",id:"lineage_flow",level:2},{value:"LOCKLESS_VIOLATION",id:"lockless_violation",level:2},{value:"LOCK_CONSISTENCY_VIOLATION",id:"lock_consistency_violation",level:2},{value:"Fixing Lock Consistency Violation reports",id:"fixing-lock-consistency-violation-reports",level:3},{value:"LOCK_ON_UI_THREAD",id:"lock_on_ui_thread",level:2},{value:"MEMORY_LEAK_C",id:"memory_leak_c",level:2},{value:"Memory leak in C",id:"memory-leak-in-c",level:3},{value:"Memory leak in Objective-C",id:"memory-leak-in-objective-c",level:3},{value:"MEMORY_LEAK_CPP",id:"memory_leak_cpp",level:2},{value:"MISSING_REQUIRED_PROP",id:"missing_required_prop",level:2},{value:"Examples",id:"examples",level:2},{value:"MIXED_SELF_WEAKSELF",id:"mixed_self_weakself",level:2},{value:"MODIFIES_IMMUTABLE",id:"modifies_immutable",level:2},{value:"MULTIPLE_WEAKSELF",id:"multiple_weakself",level:2},{value:"MUTUAL_RECURSION_CYCLE",id:"mutual_recursion_cycle",level:2},{value:"NIL_BLOCK_CALL",id:"nil_block_call",level:2},{value:"NIL_BLOCK_CALL_LATENT",id:"nil_block_call_latent",level:2},{value:"NIL_INSERTION_INTO_COLLECTION",id:"nil_insertion_into_collection",level:2},{value:"Arrays",id:"arrays",level:3},{value:"Dictionaries",id:"dictionaries",level:3},{value:"NIL_INSERTION_INTO_COLLECTION_LATENT",id:"nil_insertion_into_collection_latent",level:2},{value:"NIL_MESSAGING_TO_NON_POD",id:"nil_messaging_to_non_pod",level:2},{value:"NIL_MESSAGING_TO_NON_POD_LATENT",id:"nil_messaging_to_non_pod_latent",level:2},{value:"NO_MATCHING_BRANCH_IN_TRY",id:"no_matching_branch_in_try",level:2},{value:"NO_MATCHING_BRANCH_IN_TRY_LATENT",id:"no_matching_branch_in_try_latent",level:2},{value:"NO_MATCHING_CASE_CLAUSE",id:"no_matching_case_clause",level:2},{value:"NO_MATCHING_CASE_CLAUSE_LATENT",id:"no_matching_case_clause_latent",level:2},{value:"NO_MATCHING_ELSE_CLAUSE",id:"no_matching_else_clause",level:2},{value:"NO_MATCHING_ELSE_CLAUSE_LATENT",id:"no_matching_else_clause_latent",level:2},{value:"NO_MATCHING_FUNCTION_CLAUSE",id:"no_matching_function_clause",level:2},{value:"NO_MATCHING_FUNCTION_CLAUSE_LATENT",id:"no_matching_function_clause_latent",level:2},{value:"NO_MATCH_OF_RHS",id:"no_match_of_rhs",level:2},{value:"NO_MATCH_OF_RHS_LATENT",id:"no_match_of_rhs_latent",level:2},{value:"NO_TRUE_BRANCH_IN_IF",id:"no_true_branch_in_if",level:2},{value:"NO_TRUE_BRANCH_IN_IF_LATENT",id:"no_true_branch_in_if_latent",level:2},{value:"NSSTRING_INTERNAL_PTR_CAPTURED_IN_BLOCK",id:"nsstring_internal_ptr_captured_in_block",level:2},{value:"NULLPTR_DEREFERENCE",id:"nullptr_dereference",level:2},{value:"Null dereference in Java",id:"null-dereference-in-java",level:3},{value:"Null dereference in C",id:"null-dereference-in-c",level:3},{value:"Null dereference in Objective-C",id:"null-dereference-in-objective-c",level:3},{value:"NULLPTR_DEREFERENCE_IN_NULLSAFE_CLASS",id:"nullptr_dereference_in_nullsafe_class",level:2},{value:"Null dereference in Java",id:"null-dereference-in-java-1",level:3},{value:"Null dereference in C",id:"null-dereference-in-c-1",level:3},{value:"Null dereference in Objective-C",id:"null-dereference-in-objective-c-1",level:3},{value:"NULLPTR_DEREFERENCE_IN_NULLSAFE_CLASS_LATENT",id:"nullptr_dereference_in_nullsafe_class_latent",level:2},{value:"NULLPTR_DEREFERENCE_LATENT",id:"nullptr_dereference_latent",level:2},{value:"NULL_ARGUMENT",id:"null_argument",level:2},{value:"NULL_ARGUMENT_LATENT",id:"null_argument_latent",level:2},{value:"NULL_DEREFERENCE",id:"null_dereference",level:2},{value:"OPTIONAL_EMPTY_ACCESS",id:"optional_empty_access",level:2},{value:"OPTIONAL_EMPTY_ACCESS_LATENT",id:"optional_empty_access_latent",level:2},{value:"PREMATURE_NIL_TERMINATION_ARGUMENT",id:"premature_nil_termination_argument",level:2},{value:"PULSE_CANNOT_INSTANTIATE_ABSTRACT_CLASS",id:"pulse_cannot_instantiate_abstract_class",level:2},{value:"PULSE_CONST_REFABLE",id:"pulse_const_refable",level:2},{value:"PULSE_DICT_MISSING_KEY",id:"pulse_dict_missing_key",level:2},{value:"PULSE_DYNAMIC_TYPE_MISMATCH",id:"pulse_dynamic_type_mismatch",level:2},{value:"PULSE_READONLY_SHARED_PTR_PARAM",id:"pulse_readonly_shared_ptr_param",level:2},{value:"PULSE_REFERENCE_STABILITY",id:"pulse_reference_stability",level:2},{value:"PULSE_RESOURCE_LEAK",id:"pulse_resource_leak",level:2},{value:"PULSE_TRANSITIVE_ACCESS",id:"pulse_transitive_access",level:2},{value:"PULSE_UNAWAITED_AWAITABLE",id:"pulse_unawaited_awaitable",level:2},{value:"PULSE_UNFINISHED_BUILDER",id:"pulse_unfinished_builder",level:2},{value:"PULSE_UNINITIALIZED_CONST",id:"pulse_uninitialized_const",level:2},{value:"PULSE_UNINITIALIZED_METHOD",id:"pulse_uninitialized_method",level:2},{value:"PULSE_UNINITIALIZED_VALUE",id:"pulse_uninitialized_value",level:2},{value:"PULSE_UNNECESSARY_COPY",id:"pulse_unnecessary_copy",level:2},{value:"PULSE_UNNECESSARY_COPY_ASSIGNMENT",id:"pulse_unnecessary_copy_assignment",level:2},{value:"PULSE_UNNECESSARY_COPY_ASSIGNMENT_CONST",id:"pulse_unnecessary_copy_assignment_const",level:2},{value:"PULSE_UNNECESSARY_COPY_ASSIGNMENT_MOVABLE",id:"pulse_unnecessary_copy_assignment_movable",level:2},{value:"PULSE_UNNECESSARY_COPY_INTERMEDIATE",id:"pulse_unnecessary_copy_intermediate",level:2},{value:"PULSE_UNNECESSARY_COPY_INTERMEDIATE_CONST",id:"pulse_unnecessary_copy_intermediate_const",level:2},{value:"PULSE_UNNECESSARY_COPY_MOVABLE",id:"pulse_unnecessary_copy_movable",level:2},{value:"PULSE_UNNECESSARY_COPY_OPTIONAL",id:"pulse_unnecessary_copy_optional",level:2},{value:"PULSE_UNNECESSARY_COPY_OPTIONAL_CONST",id:"pulse_unnecessary_copy_optional_const",level:2},{value:"PULSE_UNNECESSARY_COPY_RETURN",id:"pulse_unnecessary_copy_return",level:2},{value:"PULSE_UNNECESSARY_COPY_THRIFT_ASSIGNMENT",id:"pulse_unnecessary_copy_thrift_assignment",level:2},{value:"PURE_FUNCTION",id:"pure_function",level:2},{value:"REGEX_OP_ON_UI_THREAD",id:"regex_op_on_ui_thread",level:2},{value:"RESOURCE_LEAK",id:"resource_leak",level:2},{value:"Resource leak in C",id:"resource-leak-in-c",level:3},{value:"Resource leak in Java",id:"resource-leak-in-java",level:3},{value:"Basics and Standard Idiom",id:"basics-and-standard-idiom",level:3},{value:"Multiple Resources Bugs",id:"multiple-resources-bugs",level:4},{value:"Nested_Allocations",id:"nested_allocations",level:3},{value:"Allocation of JSonParser and Cursor resources",id:"allocation-of-jsonparser-and-cursor-resources",level:3},{value:"Escaping resources and exceptions",id:"escaping-resources-and-exceptions",level:3},{value:"Java 7's try-with-resources",id:"java-7s-try-with-resources",level:3},{value:"RETAIN_CYCLE",id:"retain_cycle",level:2},{value:"RETAIN_CYCLE_NO_WEAK_INFO",id:"retain_cycle_no_weak_info",level:2},{value:"SCOPE_LEAKAGE",id:"scope_leakage",level:2},{value:"SELF_IN_BLOCK_PASSED_TO_INIT",id:"self_in_block_passed_to_init",level:2},{value:"SENSITIVE_DATA_FLOW",id:"sensitive_data_flow",level:2},{value:"STACK_VARIABLE_ADDRESS_ESCAPE",id:"stack_variable_address_escape",level:2},{value:"STARVATION",id:"starvation",level:2},{value:"STATIC_CONSTRUCTOR_STALL",id:"static_constructor_stall",level:2},{value:"STATIC_INITIALIZATION_ORDER_FIASCO",id:"static_initialization_order_fiasco",level:2},{value:"STRICT_MODE_VIOLATION",id:"strict_mode_violation",level:2},{value:"STRONG_SELF_NOT_CHECKED",id:"strong_self_not_checked",level:2},{value:"TAINT_ERROR",id:"taint_error",level:2},{value:"THREAD_SAFETY_VIOLATION",id:"thread_safety_violation",level:2},{value:"Thread-safety: What is a data race",id:"thread-safety-what-is-a-data-race",level:3},{value:"Thread-safety: Potential fixes",id:"thread-safety-potential-fixes",level:3},{value:"Thread-safety: Conditions checked before reporting",id:"thread-safety-conditions-checked-before-reporting",level:3},{value:"Thread-safety: Thread annotations recognized by RacerD",id:"thread-safety-thread-annotations-recognized-by-racerd",level:3},{value:"Thread-safety: Other annotations and what they do",id:"thread-safety-other-annotations-and-what-they-do",level:3},{value:"TOPL_ERROR",id:"topl_error",level:2},{value:"TOPL_ERROR_LATENT",id:"topl_error_latent",level:2},{value:"USE_AFTER_DELETE",id:"use_after_delete",level:2},{value:"USE_AFTER_DELETE_LATENT",id:"use_after_delete_latent",level:2},{value:"USE_AFTER_FREE",id:"use_after_free",level:2},{value:"USE_AFTER_FREE_LATENT",id:"use_after_free_latent",level:2},{value:"USE_AFTER_LIFETIME",id:"use_after_lifetime",level:2},{value:"USE_AFTER_LIFETIME_LATENT",id:"use_after_lifetime_latent",level:2},{value:"VECTOR_INVALIDATION",id:"vector_invalidation",level:2},{value:"VECTOR_INVALIDATION_LATENT",id:"vector_invalidation_latent",level:2},{value:"WEAK_SELF_IN_NO_ESCAPE_BLOCK",id:"weak_self_in_no_escape_block",level:2}];function d(e){const n={a:"a",code:"code",em:"em",h2:"h2",h3:"h3",h4:"h4",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.p,{children:"Here is an overview of the issue types currently reported by Infer."}),"\n",(0,r.jsx)(n.h2,{id:"arbitrary_code_execution_under_lock",children:"ARBITRARY_CODE_EXECUTION_UNDER_LOCK"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Arbitrary Code Execution Under lock" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-starvation",children:"starvation"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"A call that may execute arbitrary code (such as registered, or chained, callbacks) is made while holding a lock.\nThis code may deadlock whenever the callbacks obtain locks themselves, so it is an unsafe pattern."}),"\n",(0,r.jsx)(n.p,{children:"Example:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:" SettableFuture future = null;\n\n public void callFutureSet() {\n future.set(null);\n }\n\n // synchronized means it's taking a lock implicitly\n public synchronized void example_of_bad_pattern() {\n callFutureSet(); // <- issue reported here\n }\n\n // If the call is made while holding multiple locks, the warning\n // will be issued only at the innermost lock acquisition. Here we\n // report in example_of_bad_pattern but we won't report below.\n public void nested_bad_pattern_no_report(Object o) {\n synchronized (o) {\n example_of_bad_pattern(); // <- no issue reported\n }\n }\n"})}),"\n",(0,r.jsx)(n.h2,{id:"bad_arg",children:"BAD_ARG"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "Bad Arg" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["Bad arg in Erlang: Reports an error when the type of an argument is wrong or the argument is badly formed. Corresponds to the ",(0,r.jsx)(n.code,{children:"badarg"})," error in the Erlang runtime."]}),"\n",(0,r.jsxs)(n.p,{children:["For example, trying to concatenate the number ",(0,r.jsx)(n.code,{children:"3"})," with the list ",(0,r.jsx)(n.code,{children:"[1,2]"})," gives ",(0,r.jsx)(n.code,{children:"badarg"})," error because ",(0,r.jsx)(n.code,{children:"3"})," is not a list."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-erlang",children:"f() ->\n 3 ++ [1,2]. // badarg error\n"})}),"\n",(0,r.jsxs)(n.p,{children:["Note that although the first argument needs to be a list, the second argument may not be a list.\nFor instance, concatenating [1,2] with the number ",(0,r.jsx)(n.code,{children:"3"})," raises no error in Erlang."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-erlang",children:"g() ->\n [1,2] ++ 3. // no error. Result: [1,2|3]\n"})}),"\n",(0,r.jsx)(n.h2,{id:"bad_arg_latent",children:"BAD_ARG_LATENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "Bad Arg Latent" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A latent ",(0,r.jsx)(n.a,{href:"#bad_arg",children:"BAD_ARG"}),". See the ",(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse#latent-issues",children:"documentation on Pulse latent issues"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"bad_generator",children:"BAD_GENERATOR"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "Bad Generator" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["Bad generator in Erlang: Reports an error when a wrong type is used in a generator. Corresponds to the ",(0,r.jsx)(n.code,{children:"bad_generator"})," error in the Erlang runtime."]}),"\n",(0,r.jsx)(n.p,{children:"For example:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-erlang",children:"list_instead_of_map() ->\n M = [],\n [{K, V} || K := V <- M]\n"})}),"\n",(0,r.jsx)(n.h2,{id:"bad_generator_latent",children:"BAD_GENERATOR_LATENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "Bad Generator Latent" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A latent ",(0,r.jsx)(n.a,{href:"#bad_generator",children:"BAD_GENERATOR"}),". See the ",(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse#latent-issues",children:"documentation on Pulse latent issues"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"bad_key",children:"BAD_KEY"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "Bad Key" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["Bad key in Erlang: Reports an error when trying to access or update a non-existing key in a map. Corresponds to the ",(0,r.jsx)(n.code,{children:"{badkey,K}"})," error in the Erlang runtime."]}),"\n",(0,r.jsxs)(n.p,{children:["For example, trying to update the key ",(0,r.jsx)(n.code,{children:"2"})," in ",(0,r.jsx)(n.code,{children:"M"})," gives ",(0,r.jsx)(n.code,{children:"{badkey,2}"})," error because ",(0,r.jsx)(n.code,{children:"2"})," is not present as a key in ",(0,r.jsx)(n.code,{children:"M"}),"."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-erlang",children:"f() ->\n M = #{},\n M#{2 := 3}.\n"})}),"\n",(0,r.jsx)(n.p,{children:"Note that maps currently use a recency abstraction, meaning that only the most recent key/value is tracked.\nTherefore, if a map is non-empty and we try to access a key other than the one we track, we just assume that it is there to avoid false positives."}),"\n",(0,r.jsx)(n.h2,{id:"bad_key_latent",children:"BAD_KEY_LATENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "Bad Key Latent" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A latent ",(0,r.jsx)(n.a,{href:"#bad_key",children:"BAD_KEY"}),". See the ",(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse#latent-issues",children:"documentation on Pulse latent issues"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"bad_map",children:"BAD_MAP"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "Bad Map" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["Bad map in Erlang: Reports an error when trying to access or update a key for a term that is not a map. Corresponds to the ",(0,r.jsx)(n.code,{children:"{badmap,...}"})," error in the Erlang runtime."]}),"\n",(0,r.jsxs)(n.p,{children:["For example, trying to update ",(0,r.jsx)(n.code,{children:"L"})," as if it was a map gives ",(0,r.jsx)(n.code,{children:"{badmap,[1,2,3]}"})," error because ",(0,r.jsx)(n.code,{children:"L"})," is actually a list (",(0,r.jsx)(n.code,{children:"[1,2,3]"}),")."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-erlang",children:"f() ->\n L = [1,2,3],\n L#{1 => 2}.\n"})}),"\n",(0,r.jsx)(n.h2,{id:"bad_map_latent",children:"BAD_MAP_LATENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "Bad Map Latent" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A latent ",(0,r.jsx)(n.a,{href:"#bad_map",children:"BAD_MAP"}),". See the ",(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse#latent-issues",children:"documentation on Pulse latent issues"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"bad_record",children:"BAD_RECORD"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "Bad Record" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["Bad record in Erlang: Reports an error when trying to access or update a record with the wrong name. Corresponds to the ",(0,r.jsx)(n.code,{children:"{badrecord,Name}"})," error in the Erlang runtime."]}),"\n",(0,r.jsxs)(n.p,{children:["For example, accessing ",(0,r.jsx)(n.code,{children:"R"})," as a ",(0,r.jsx)(n.code,{children:"person"})," record gives ",(0,r.jsx)(n.code,{children:"{badrecord,person}"})," error because ",(0,r.jsx)(n.code,{children:"R"})," is ",(0,r.jsx)(n.code,{children:"rabbit"})," (even though both share the ",(0,r.jsx)(n.code,{children:"name"})," field)."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-erlang",children:'-record(person, {name, phone}).\n-record(rabbit, {name, color}).\n\nf() ->\n R = #rabbit{name = "Bunny", color = "Brown"},\n R#person.name.\n'})}),"\n",(0,r.jsx)(n.h2,{id:"bad_record_latent",children:"BAD_RECORD_LATENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "Bad Record Latent" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A latent ",(0,r.jsx)(n.a,{href:"#bad_record",children:"BAD_RECORD"}),". See the ",(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse#latent-issues",children:"documentation on Pulse latent issues"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"bad_return",children:"BAD_RETURN"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Bad Return" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"Bad return in Erlang: The dynamic type of a returned value disagrees with the static type given in the spec."}),"\n",(0,r.jsx)(n.p,{children:"For example, this function returns an integer, while the spec says it returns an atom."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-erlang",children:"-spec f() -> atom().\nf() -> 1.\n"})}),"\n",(0,r.jsxs)(n.p,{children:["Note that this will ",(0,r.jsx)(n.em,{children:"not"})," lead to a runtime error when running the Erlang program."]}),"\n",(0,r.jsx)(n.h2,{id:"bad_return_latent",children:"BAD_RETURN_LATENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Bad Return Latent" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A latent ",(0,r.jsx)(n.a,{href:"#bad_return",children:"BAD_RETURN"}),". See the ",(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse#latent-issues",children:"documentation on Pulse latent issues"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"biabduction_memory_leak",children:"BIABDUCTION_MEMORY_LEAK"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#resource-leak",children:"Resource leak"}),'. Reported as "Memory Leak" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-biabduction",children:"biabduction"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["See ",(0,r.jsx)(n.a,{href:"#memory_leak_c",children:"MEMORY_LEAK_C"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"biabduction_retain_cycle",children:"BIABDUCTION_RETAIN_CYCLE"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#resource-leak",children:"Resource leak"}),'. Reported as "Retain Cycle" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-biabduction",children:"biabduction"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["See ",(0,r.jsx)(n.a,{href:"#retain_cycle",children:"RETAIN_CYCLE"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"block_parameter_not_null_checked",children:"BLOCK_PARAMETER_NOT_NULL_CHECKED"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#null-pointer-dereference",children:"Null pointer dereference"}),'. Reported as "Block Parameter Not Null Checked" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-parameter-not-null-checked",children:"parameter-not-null-checked"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This error type is reported only in Objective-C/Objective-C++. It happens when a method has a block as a parameter,\nand the block is executed in the method's body without checking it for ",(0,r.jsx)(n.code,{children:"nil"})," first. If a ",(0,r.jsx)(n.code,{children:"nil"})," block is passed to\nthe method, then this will cause a crash. For example:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objectivec",children:"- (void)uploadTaskWithRequest:(NSURLRequest*)urlRequest\n fromFile:(NSURL*)fileURL\n delegate:(id)delegate\n delegateQueue:(NSOperationQueue*)delegateQueue\n completion:(void (^)())completion {\n ...\n completion();\n}\n"})}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"Action"}),":\nPossible solutions are adding a check for ",(0,r.jsx)(n.code,{children:"nil"}),", or making sure that the method\nis not ever called with ",(0,r.jsx)(n.code,{children:"nil"}),". When an argument will never be ",(0,r.jsx)(n.code,{children:"nil"}),", you can add\nthe annotation ",(0,r.jsx)(n.code,{children:"nonnull"})," to the argument's type, to tell Infer (and the type\nsystem), that the argument won't be ",(0,r.jsx)(n.code,{children:"nil"}),". This will silence the warning."]}),"\n",(0,r.jsx)(n.h2,{id:"buffer_overrun_l1",children:"BUFFER_OVERRUN_L1"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Buffer Overrun L1" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-bufferoverrun",children:"bufferoverrun"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"This is reported when outside of buffer bound is accessed. It can corrupt memory and may introduce\nsecurity issues in C/C++."}),"\n",(0,r.jsxs)(n.p,{children:["For example, ",(0,r.jsx)(n.code,{children:"int a[3]; a[5] = 42;"})," generates a ",(0,r.jsx)(n.code,{children:"BUFFER_OVERRUN_L1"})," on ",(0,r.jsx)(n.code,{children:"a[5] = 42;"}),"."]}),"\n",(0,r.jsx)(n.p,{children:'Buffer overrun reports fall into several "buckets" corresponding to the expected precision of the\nreport. The higher the number, the more likely it is to be a false positive.'}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"L1"}),": The most faithful report, when it ",(0,r.jsx)(n.em,{children:"must"})," be unsafe. For example, array size: ",(0,r.jsx)(n.code,{children:"[3,3]"}),",\noffset: ",(0,r.jsx)(n.code,{children:"[5,5]"}),"."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"L2"}),": Less faithful report than ",(0,r.jsx)(n.code,{children:"L1"}),", when it ",(0,r.jsx)(n.em,{children:"may"})," be unsafe. For example, array size:",(0,r.jsx)(n.code,{children:"[3,3]"}),",\noffset: ",(0,r.jsx)(n.code,{children:"[0,5]"}),". Note that the offset may be a safe value in the real execution, i.e. safe when\n0, 1, or 2; unsafe when 3, 4, or 5."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"L5"}),": The least faithful report, when there is an interval top. For example, array size:\n",(0,r.jsx)(n.code,{children:"[3,3]"}),", offset: ",(0,r.jsx)(n.code,{children:"[-oo,+oo]"}),"."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"L4"}),": More faithful report than ",(0,r.jsx)(n.code,{children:"L5"}),", when there is an infinity value. For example, array size:\n",(0,r.jsx)(n.code,{children:"[3,3]"}),", offset: ",(0,r.jsx)(n.code,{children:"[0, +oo]"}),"."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"L3"}),": The reports that are not included in the above cases."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"S2"}),": An array access is unsafe by symbolic values. For example, array size: ",(0,r.jsx)(n.code,{children:"[n,n]"}),", offset\n",(0,r.jsx)(n.code,{children:"[n,+oo]"}),"."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"U5"}),": An array access is unsafe by unknown values, which are usually from unknown function\ncalls."]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"buffer_overrun_l2",children:"BUFFER_OVERRUN_L2"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Buffer Overrun L2" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-bufferoverrun",children:"bufferoverrun"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["See ",(0,r.jsx)(n.a,{href:"#buffer_overrun_l1",children:"BUFFER_OVERRUN_L1"})]}),"\n",(0,r.jsx)(n.h2,{id:"buffer_overrun_l3",children:"BUFFER_OVERRUN_L3"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Buffer Overrun L3" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-bufferoverrun",children:"bufferoverrun"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["See ",(0,r.jsx)(n.a,{href:"#buffer_overrun_l1",children:"BUFFER_OVERRUN_L1"})]}),"\n",(0,r.jsx)(n.h2,{id:"buffer_overrun_l4",children:"BUFFER_OVERRUN_L4"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Buffer Overrun L4" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-bufferoverrun",children:"bufferoverrun"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["See ",(0,r.jsx)(n.a,{href:"#buffer_overrun_l1",children:"BUFFER_OVERRUN_L1"})]}),"\n",(0,r.jsx)(n.h2,{id:"buffer_overrun_l5",children:"BUFFER_OVERRUN_L5"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Buffer Overrun L5" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-bufferoverrun",children:"bufferoverrun"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["See ",(0,r.jsx)(n.a,{href:"#buffer_overrun_l1",children:"BUFFER_OVERRUN_L1"})]}),"\n",(0,r.jsx)(n.h2,{id:"buffer_overrun_s2",children:"BUFFER_OVERRUN_S2"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Buffer Overrun S2" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-bufferoverrun",children:"bufferoverrun"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["See ",(0,r.jsx)(n.a,{href:"#buffer_overrun_l1",children:"BUFFER_OVERRUN_L1"})]}),"\n",(0,r.jsx)(n.h2,{id:"buffer_overrun_u5",children:"BUFFER_OVERRUN_U5"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Buffer Overrun U5" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-bufferoverrun",children:"bufferoverrun"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["See ",(0,r.jsx)(n.a,{href:"#buffer_overrun_l1",children:"BUFFER_OVERRUN_L1"})]}),"\n",(0,r.jsx)(n.h2,{id:"captured_strong_self",children:"CAPTURED_STRONG_SELF"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#resource-leak",children:"Resource leak"}),'. Reported as "Captured strongSelf" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-self-in-block",children:"self-in-block"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This check is about when a strong pointer to ",(0,r.jsx)(n.code,{children:"self"})," is captured in a block.\nThis could lead to retain cycles or unexpected behavior since to avoid retain\ncycles one usually uses a local strong pointer or a captured weak pointer instead."]}),"\n",(0,r.jsx)(n.p,{children:"This will happen in one of two cases generally:"}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsxs)(n.li,{children:["One uses ",(0,r.jsx)(n.code,{children:"weakSelf"})," but forgot to declare it weak first."]}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"Example:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objectivec",children:" __typeof(self) weakSelf = self;\n int (^my_block)(BOOL) = ^(BOOL isTapped) {\n __strong __typeof(weakSelf) strongSelf = weakSelf;\n return strongSelf->x;\n };\n"})}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"Action:"})," Replace the first line with ",(0,r.jsx)(n.code,{children:"__weak __typeof(self) weakSelf = self;"}),"."]}),"\n",(0,r.jsxs)(n.ol,{start:"2",children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["One is using ",(0,r.jsx)(n.code,{children:"strongSelf"}),", declared in a block, in another inner block.\nThe retain cycle is avoided in the outer block because ",(0,r.jsx)(n.code,{children:"strongSelf"})," is a\nlocal variable of the block. If ",(0,r.jsx)(n.code,{children:"strongSelf"})," is used in the inner block,\nthen it's not a local variable anymore, but a captured variable."]}),"\n",(0,r.jsx)(n.p,{children:"Example:"}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objectivec",children:" __weak __typeof(self) weakSelf = self;\n int (^my_block)() = ^() {\n __strong typeof(self) strongSelf = weakSelf;\n if (strongSelf) {\n int (^my_block)() = ^() {\n int x = strongSelf->x;\n ...\n };\n ...\n }\n ...\n };\n"})}),"\n",(0,r.jsxs)(n.p,{children:["In this example, ",(0,r.jsx)(n.code,{children:"strongSelf"})," is a captured variable of the inner block, and this could cause retain cycles."]}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"Action:"})," Use a new pointer to self local to the inner block. In the example:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objectivec",children:" __weak __typeof(self) weakSelf = self;\n int (^my_block)() = ^() {\n __strong typeof(self) strongSelf = weakSelf;\n if (strongSelf) {\n int (^my_block)() = ^() {\n __typeof(self) innerStrongSelf = weakSelf;\n int x = innerStrongSelf->x;\n ...\n };\n ...\n }\n ...\n };\n"})}),"\n",(0,r.jsx)(n.p,{children:"Or, to improve readability, move the inner block logic into a separate method."}),"\n",(0,r.jsx)(n.p,{children:"Another solution could be to copy the instance variable that one needs to access inside the inner block to a local variable, and use the local variable instead:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objectivec",children:" __weak __typeof(self) weakSelf = self;\n int (^my_block)() = ^() {\n __strong typeof(self) strongSelf = weakSelf;\n if (strongSelf) {\n int my_x = strongSelf->x;\n int (^my_block)() = ^() {\n int x = my_x;\n ...\n };\n ...\n }\n ...\n };\n"})}),"\n",(0,r.jsx)(n.h2,{id:"checkers_allocates_memory",children:"CHECKERS_ALLOCATES_MEMORY"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#perf-regression",children:"Perf regression"}),'. Reported as "Allocates Memory" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-annotation-reachability",children:"annotation-reachability"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A method annotated with ",(0,r.jsx)(n.code,{children:"@NoAllocation"})," transitively calls ",(0,r.jsx)(n.code,{children:"new"}),"."]}),"\n",(0,r.jsx)(n.p,{children:"Example:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"class C implements I {\n @NoAllocation\n void directlyAllocatingMethod() {\n new Object();\n }\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"checkers_annotation_reachability_error",children:"CHECKERS_ANNOTATION_REACHABILITY_ERROR"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#user-defined-property",children:"User defined property"}),'. Reported as "Annotation Reachability Error" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-annotation-reachability",children:"annotation-reachability"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A method annotated with an annotation ",(0,r.jsx)(n.code,{children:"@A"})," transitively calls a method annotated ",(0,r.jsx)(n.code,{children:"@B"})," where the combination of annotations is forbidden (for example, ",(0,r.jsx)(n.code,{children:"@UiThread"})," calling ",(0,r.jsx)(n.code,{children:"@WorkerThread"}),")."]}),"\n",(0,r.jsx)(n.h2,{id:"checkers_calls_expensive_method",children:"CHECKERS_CALLS_EXPENSIVE_METHOD"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#perf-regression",children:"Perf regression"}),'. Reported as "Expensive Method Called" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-annotation-reachability",children:"annotation-reachability"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A method annotated with ",(0,r.jsx)(n.code,{children:"@PerformanceCritical"})," transitively calls a method annotated ",(0,r.jsx)(n.code,{children:"@Expensive"}),"."]}),"\n",(0,r.jsx)(n.p,{children:"Example:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"class C {\n @PerformanceCritical\n void perfCritical() {\n expensive();\n }\n\n @Expensive\n void expensive() {}\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"checkers_expensive_overrides_unannotated",children:"CHECKERS_EXPENSIVE_OVERRIDES_UNANNOTATED"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Expensive Overrides Unannotated" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-annotation-reachability",children:"annotation-reachability"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A method annotated with ",(0,r.jsx)(n.code,{children:"@Expensive"})," overrides an un-annotated method."]}),"\n",(0,r.jsx)(n.p,{children:"Example:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"interface I {\n void foo();\n}\n\nclass A implements I {\n @Expensive\n public void foo() {}\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"checkers_fragment_retains_view",children:"CHECKERS_FRAGMENT_RETAINS_VIEW"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#resource-leak",children:"Resource leak"}),'. Reported as "Fragment Retains View" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-fragment-retains-view",children:"fragment-retains-view"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This error type is Android-specific. It fires when a ",(0,r.jsx)(n.code,{children:"Fragment"})," type fails to\nnullify one or more of its declared ",(0,r.jsx)(n.code,{children:"View"})," fields in ",(0,r.jsx)(n.code,{children:"onDestroyView"}),". In\nperformance-sensitive applications, a ",(0,r.jsx)(n.code,{children:"Fragment"})," should initialize all ",(0,r.jsx)(n.code,{children:"View"}),"'s\nin ",(0,r.jsx)(n.code,{children:"onCreateView"})," and nullify them in ",(0,r.jsx)(n.code,{children:"onDestroyView"}),". If a ",(0,r.jsx)(n.code,{children:"Fragment"})," is placed\non the back stack and fails to nullify a ",(0,r.jsx)(n.code,{children:"View"})," in ",(0,r.jsx)(n.code,{children:"onDestroyView"}),", it will\nretain a useless reference to that ",(0,r.jsx)(n.code,{children:"View"})," that will not be cleaned up until the\n",(0,r.jsx)(n.code,{children:"Fragment"})," is resumed or destroyed."]}),"\n",(0,r.jsxs)(n.p,{children:["Action: Nullify the ",(0,r.jsx)(n.code,{children:"View"})," in question in ",(0,r.jsx)(n.code,{children:"onDestroyView"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"compared_to_null_and_dereferenced",children:"COMPARED_TO_NULL_AND_DEREFERENCED"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#null-pointer-dereference",children:"Null pointer dereference"}),'. Reported as "Compared To Null And Dereferenced" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"A pointer that has both been compared to null, whcich suggests that it could be null, but has also been dereferenced without a null check."}),"\n",(0,r.jsx)(n.h2,{id:"config_impact",children:"CONFIG_IMPACT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#perf-regression",children:"Perf regression"}),'. Reported as "Config Impact" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-config-impact-analysis",children:"config-impact-analysis"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["Infer reports this issue when an ",(0,r.jsx)(n.em,{children:"expensive"})," function is called without a ",(0,r.jsx)(n.em,{children:"config check"}),". The\n",(0,r.jsx)(n.em,{children:"config"})," is usually a boolean value that enables experimental new features and it is defined per\napplication/codebase, e.g. gatekeepers. To determine whether a function is expensive or not, the\nchecker relies on modeled functions that are assumed to be expensive, e.g. string operations,\nregular expression match, or DB accesses."]}),"\n",(0,r.jsxs)(n.p,{children:["Similar to ",(0,r.jsx)(n.a,{href:"/docs/next/checker-cost",children:"Cost analysis"}),", this issue type is reported only in\ndifferential mode, i.e. when there are original code and modified one and we can compare Infer's\nresults on both of them."]}),"\n",(0,r.jsx)(n.p,{children:"For instance, if we have the following code"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"// version1\nfoo();\nif (config_check){\n bar();\n}\n"})}),"\n",(0,r.jsx)(n.p,{children:"which is then modified to next"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"// version2\nfoo();\nif (config_check){\n bar();\n}\ngoo(); // added\n"})}),"\n",(0,r.jsxs)(n.p,{children:['the analysis would warn the developer that "',(0,r.jsx)(n.code,{children:"goo()"}),' is a newly added function call and it might\ncause an unexpected new behavior". However, if we were to add ',(0,r.jsx)(n.code,{children:"goo()"})," right after ",(0,r.jsx)(n.code,{children:"bar()"}),", then\nInfer wouldn't warn about it because it is already gated under the ",(0,r.jsx)(n.code,{children:"config_check"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["The analysis is inter-procedural: it can reason about impacts by code changes not only inside a\nsingle procedure, but also the impacts that are propagated by function calls. Thus, if we were to\nmodify ",(0,r.jsx)(n.code,{children:"version1"})," to ",(0,r.jsx)(n.code,{children:"version3"})," below by calling ",(0,r.jsx)(n.code,{children:"goo()"})," in ",(0,r.jsx)(n.code,{children:"foo()"}),","]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"// version3\nvoid foo(){\n // ....\n goo(); // added\n}\n"})}),"\n",(0,r.jsxs)(n.p,{children:["then the analysis will report a ",(0,r.jsx)(n.code,{children:"CONFIG_IMPACT"})," issue on the ungated call site of ",(0,r.jsx)(n.code,{children:"foo()"}),"."]}),"\n",(0,r.jsx)(n.p,{children:"Currently, the analysis supports both Objective-C and Java but not C++."}),"\n",(0,r.jsx)(n.p,{children:"Action: Make sure the ungated code change is semantically correct and harmless in terms of execution\ncost. If you are not sure, gate it with a new or pre-existing config."}),"\n",(0,r.jsx)(n.h2,{id:"config_impact_strict",children:"CONFIG_IMPACT_STRICT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#ungated-code",children:"Ungated code"}),'. Reported as "Config Impact Strict" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-config-impact-analysis",children:"config-impact-analysis"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This is similar to ",(0,r.jsxs)(n.a,{href:"#config_impact",children:[(0,r.jsx)(n.code,{children:"CONFIG_IMPACT"})," issue"]})," but the analysis reports ",(0,r.jsx)(n.strong,{children:"all"})," ungated\ncodes irrespective of whether they are expensive or not."]}),"\n",(0,r.jsx)(n.h2,{id:"config_usage",children:"CONFIG_USAGE"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Config Usage" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["Infer reports this issue when a ",(0,r.jsx)(n.em,{children:"config"})," value is used as branch condition in a function. The\n",(0,r.jsx)(n.em,{children:"config"})," is usually a boolean value that enables experimental new features and it is defined per\napplication/codebase, e.g. gatekeepers."]}),"\n",(0,r.jsx)(n.p,{children:"For instance, if we have the following code"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-cpp",children:'void foo() {\n if(config_check("my_new_feature")){ ... }\n}\n'})}),"\n",(0,r.jsxs)(n.p,{children:['then analysis would provide information that "the function ',(0,r.jsx)(n.code,{children:"foo"})," uses the config ",(0,r.jsx)(n.code,{children:"my_new_feature"}),' as\nbranch condition".']}),"\n",(0,r.jsx)(n.p,{children:"Note: This type of issue is only for providing semantic information, rather than warning or\nreporting actual problem."}),"\n",(0,r.jsx)(n.h2,{id:"constant_address_dereference",children:"CONSTANT_ADDRESS_DEREFERENCE"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Constant Address Dereference" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This is reported when an address at an absolute location, e.g. 1234,\nis dereferenced. It is a more general version of the\n",(0,r.jsx)(n.a,{href:"#nullptr_dereference",children:(0,r.jsx)(n.code,{children:"NULLPTR_DEREFERENCE"})})," error type that is\nreported when the address is a constant other than zero."]}),"\n",(0,r.jsxs)(n.p,{children:["For example, ",(0,r.jsx)(n.code,{children:"int *p = (int *) 123; *p = 42;"})," generates a ",(0,r.jsx)(n.code,{children:"CONSTANT_ADDRESS_DEREFERENCE"})," on ",(0,r.jsx)(n.code,{children:"*p = 42;"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["For more information see the ",(0,r.jsx)(n.a,{href:"#nullptr_dereference",children:(0,r.jsx)(n.code,{children:"NULLPTR_DEREFERENCE"})})," issue type."]}),"\n",(0,r.jsx)(n.h2,{id:"constant_address_dereference_latent",children:"CONSTANT_ADDRESS_DEREFERENCE_LATENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Constant Address Dereference Latent" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A latent ",(0,r.jsx)(n.a,{href:"#constant_address_dereference",children:"CONSTANT_ADDRESS_DEREFERENCE"}),". See the ",(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse#latent-issues",children:"documentation on Pulse latent issues"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"cxx_ref_captured_in_block",children:"CXX_REF_CAPTURED_IN_BLOCK"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#memory-error",children:"Memory error"}),'. Reported as "C++ Reference Captured in Block" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-self-in-block",children:"self-in-block"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This check flags when a C++ reference is captured in an escaping block.\nThis means that the block will be leaving the current scope, i.e. it is\nnot annotated with ",(0,r.jsx)(n.code,{children:"__attribute__((noescape))"}),"."]}),"\n",(0,r.jsx)(n.p,{children:"Example:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"- (void)ref_captured_in_escaping_block_bad:(int&)y {\n dispatch_async(dispatch_get_main_queue(), ^{\n int a = y;\n ...\n });\n ...;\n}\n"})}),"\n",(0,r.jsx)(n.p,{children:"This could cause crashes because C++ references are not managed pointers\n(like ARC pointers) and so the referent is likely to be gone if the block\ndereferences it later."}),"\n",(0,r.jsx)(n.h2,{id:"cxx_string_captured_in_block",children:"CXX_STRING_CAPTURED_IN_BLOCK"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#memory-error",children:"Memory error"}),'. Reported as "C++ String Captured in Block" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-self-in-block",children:"self-in-block"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This check flags when an internal pointer of a local variable of type ",(0,r.jsx)(n.code,{children:"std::string"})," is captured in an escaping block.\nThis means that the block will be leaving the current scope, i.e. it is\nnot annotated with ",(0,r.jsx)(n.code,{children:"__attribute__((noescape))"}),"."]}),"\n",(0,r.jsx)(n.p,{children:"Example:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:" std::string fullName;\n const char* c = fullName.c_str();\n dispatch_async(dispatch_get_main_queue(), ^{\n const char* c1 = c;\n });\n"})}),"\n",(0,r.jsx)(n.p,{children:"This could cause crashes because the variable is likely to be freed when the code is executed, leaving the pointer dangling."}),"\n",(0,r.jsx)(n.h2,{id:"dangling_pointer_dereference",children:"DANGLING_POINTER_DEREFERENCE"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Dangling Pointer Dereference" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-biabduction",children:"biabduction"}),"."]})}),"\n",(0,r.jsx)(n.h2,{id:"data_flow_to_sink",children:"DATA_FLOW_TO_SINK"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#sensitive-data-flow",children:"Sensitive data flow"}),'. Reported as "Data Flow to Sink" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"A flow of data was detected to a sink."}),"\n",(0,r.jsx)(n.h2,{id:"deadlock",children:"DEADLOCK"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#concurrency",children:"Concurrency"}),'. Reported as "Deadlock" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-starvation",children:"starvation"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"This error is currently reported in Java. A deadlock occurs when two distinct\nthreads try to acquire two locks in reverse orders. The following code\nillustrates a textbook example. Of course, in real deadlocks, the lock\nacquisitions may be separated by deeply nested call chains."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:" public void lockAThenB() {\n synchronized(lockA) {\n synchronized(lockB) {\n // do something with both resources\n }\n }\n }\n\n public void lockBThenA() {\n synchronized(lockB) {\n synchronized(lockA) {\n // do something with both resources\n }\n }\n }\n"})}),"\n",(0,r.jsx)(n.p,{children:"The standard solution to a deadlock is to fix an order of lock acquisition and\nadhere to that order in all cases. Another solution may be to shrink the\ncritical sections (i.e., the code executing under lock) to the minimum required."}),"\n",(0,r.jsxs)(n.p,{children:["Old-style containers such as ",(0,r.jsx)(n.code,{children:"Vector"})," are synchronized on the object monitor,\nwhich means that deadlocks can occur even without explicit synchronisation on\nboth threads. For instance:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:" public void lockAThenAddToVector() {\n synchronized(lockA) {\n vector.add(object);\n }\n }\n\n public void lockVectorThenA() {\n synchronized(vector) {\n synchronized(lockA) {\n // do something with both resources\n }\n }\n }\n"})}),"\n",(0,r.jsx)(n.p,{children:"Infer has support for detecting these deadlocks too."}),"\n",(0,r.jsxs)(n.p,{children:["To suppress reports of deadlocks in a method ",(0,r.jsx)(n.code,{children:"m()"})," use the\n",(0,r.jsx)(n.code,{children:'@SuppressLint("DEADLOCK")'})," annotation, as follows:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:' import android.annotation.SuppressLint;\n\n @SuppressLint("DEADLOCK")\n public void m() {\n ...\n }\n'})}),"\n",(0,r.jsx)(n.h2,{id:"dead_store",children:"DEAD_STORE"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#logic-error",children:"Logic error"}),'. Reported as "Dead Store" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-liveness",children:"liveness"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This error is reported in C++. It fires when the value assigned to a variables\nis never used (e.g., ",(0,r.jsx)(n.code,{children:"int i = 1; i = 2; return i;"}),")."]}),"\n",(0,r.jsx)(n.h2,{id:"divide_by_zero",children:"DIVIDE_BY_ZERO"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Divide By Zero" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-biabduction",children:"biabduction"}),"."]})}),"\n",(0,r.jsx)(n.h2,{id:"empty_vector_access",children:"EMPTY_VECTOR_ACCESS"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Empty Vector Access" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-biabduction",children:"biabduction"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"This error type is reported only in C++, in versions >= C++11."}),"\n",(0,r.jsx)(n.p,{children:"The code is trying to access an element of a vector that Infer believes to be\nempty. Such an access will cause undefined behavior at runtime."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-cpp",children:"#include \nint foo(){\n const std::vector vec;\n return vec[0]; // Empty vector access reported here\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"execution_time_complexity_increase",children:"EXECUTION_TIME_COMPLEXITY_INCREASE"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Execution Time Complexity Increase" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-cost",children:"cost"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["Infer reports this issue when the execution time complexity of a\nprogram increases in degree: e.g. from constant to linear or from\nlogarithmic to quadratic. This issue type is only reported in\ndifferential mode: i.e when we are comparing the cost analysis results of\ntwo runs of infer on a file. Check out examples in ",(0,r.jsx)(n.a,{href:"/docs/next/checker-cost#examples-execution-cost",children:"here"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"execution_time_complexity_increase_ui_thread",children:"EXECUTION_TIME_COMPLEXITY_INCREASE_UI_THREAD"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Execution Time Complexity Increase Ui Thread" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-cost",children:"cost"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["Infer reports this issue when the execution time complexity of the procedure increases in degree ",(0,r.jsx)(n.strong,{children:"and"})," the procedure runs on the UI (main) thread."]}),"\n",(0,r.jsx)(n.p,{children:"Infer considers a method as running on the UI thread whenever:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["The method, one of its overrides, its class, or an ancestral class, is\nannotated with ",(0,r.jsx)(n.code,{children:"@UiThread"}),"."]}),"\n",(0,r.jsxs)(n.li,{children:["The method, or one of its overrides is annotated with ",(0,r.jsx)(n.code,{children:"@OnEvent"}),", ",(0,r.jsx)(n.code,{children:"@OnClick"}),",\netc."]}),"\n",(0,r.jsxs)(n.li,{children:["The method or its callees call a ",(0,r.jsx)(n.code,{children:"Litho.ThreadUtils"})," method such as\n",(0,r.jsx)(n.code,{children:"assertMainThread"}),"."]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"execution_time_unreachable_at_exit",children:"EXECUTION_TIME_UNREACHABLE_AT_EXIT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Execution Time Unreachable At Exit" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-cost",children:"cost"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"This issue type indicates that the program's execution doesn't reach\nthe exit node (where our analysis computes the final cost of the\nprocedure). Hence, we cannot compute a static bound for the procedure."}),"\n",(0,r.jsx)(n.p,{children:"Examples:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"void exit_unreachable() {\n exit(0); // modeled as unreachable\n}\n\nvoid infeasible_path_unreachable() {\n Preconditions.checkState(false); // like assert false, state pruned to bottom\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"expensive_execution_time",children:"EXPENSIVE_EXECUTION_TIME"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Expensive Execution Time" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-cost",children:"cost"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["[EXPERIMENTAL] This warning indicates that the procedure has non-constant and non-top execution cost. By default, this issue type is disabled. To enable it, set ",(0,r.jsx)(n.code,{children:"enabled=true"})," in ",(0,r.jsx)(n.a,{href:"https://github.com/facebook/infer/blob/main/infer/src/base/costKind.ml#L55",children:"costKind.ml"}),"."]}),"\n",(0,r.jsx)(n.p,{children:"For instance, a simple example where we report this issue is a function with linear cost:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"int sum_linear(ArrayList list){\n int sum = 0;\n for (Integer el: list){\n sum += el;\n }\n return sum;\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"expensive_loop_invariant_call",children:"EXPENSIVE_LOOP_INVARIANT_CALL"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Expensive Loop Invariant Call" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-loop-hoisting",children:"loop-hoisting"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["We report this issue type when a function is ",(0,r.jsx)(n.a,{href:"/docs/next/all-issue-types#invariant_call",children:"loop-invariant"})," and also expensive (i.e. at least has linear complexity as determined by the ",(0,r.jsx)(n.a,{href:"/docs/next/checker-cost",children:"cost"})," analysis)."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"int incr(int x) {\n return x + 1;\n}\n\n// incr will not be hoisted since it is cheap(constant time)\nvoid foo_linear(int size) {\n int x = 10;\n for (int i = 0; i < size; i++) {\n incr(x); // constant call, don't hoist\n }\n}\n\n// call to foo_linear will be hoisted since it is expensive(linear in size).\nvoid symbolic_expensive_hoist(int size) {\n for (int i = 0; i < size; i++) {\n foo_linear(size); // hoist\n }\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"guardedby_violation",children:"GUARDEDBY_VIOLATION"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#concurrency",children:"Concurrency"}),'. Reported as "GuardedBy Violation" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-racerd",children:"racerd"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A field annotated with ",(0,r.jsx)(n.code,{children:"@GuardedBy"})," is being accessed by a call-chain that starts at a non-private method without synchronization."]}),"\n",(0,r.jsx)(n.p,{children:"Example:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:'class C {\n @GuardedBy("this")\n String f;\n\n void foo(String s) {\n f = s; // unprotected access here\n }\n}\n'})}),"\n",(0,r.jsxs)(n.p,{children:["Action: Protect the offending access by acquiring the lock indicated by the ",(0,r.jsx)(n.code,{children:"@GuardedBy(...)"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"impure_function",children:"IMPURE_FUNCTION"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Impure Function" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-impurity",children:"impurity"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"This issue type indicates impure functions. For instance, below functions would be marked as impure:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"void makeAllZero_impure(ArrayList list) {\n Iterator listIterator = list.iterator();\n while (listIterator.hasNext()) {\n Foo foo = listIterator.next();\n foo.x = 0;\n }\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"inefficient_keyset_iterator",children:"INEFFICIENT_KEYSET_ITERATOR"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#perf-regression",children:"Perf regression"}),'. Reported as "Inefficient Keyset Iterator" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-inefficient-keyset-iterator",children:"inefficient-keyset-iterator"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"This issue is raised when"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["iterating over a HashMap with ",(0,r.jsx)(n.code,{children:"keySet()"})," iterator"]}),"\n",(0,r.jsx)(n.li,{children:"looking up the key each time"}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"Example:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"void inefficient_loop_bad(HashMap testMap) {\n for (String key : testMap.keySet()) {\n Integer value = testMap.get(key); // extra look-up cost\n foo(key, value);\n }\n}\n"})}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"Action"}),":"]}),"\n",(0,r.jsxs)(n.p,{children:["Instead, it is more efficient to iterate over the loop with ",(0,r.jsx)(n.code,{children:"entrySet"})," which returns key-vaue pairs and gets rid of the hashMap lookup."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"void efficient_loop_ok(HashMap testMap) {\n for (Map.Entry entry : testMap.entrySet()) {\n String key = entry.getKey();\n Integer value = entry.getValue();\n foo(key, value);\n }\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"inferbo_alloc_is_big",children:"INFERBO_ALLOC_IS_BIG"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Alloc Is Big" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-bufferoverrun",children:"bufferoverrun"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"malloc"})," is passed a large constant value (>=10^6). For example, ",(0,r.jsx)(n.code,{children:"int n = 1000000; malloc(n);"})," generates ",(0,r.jsx)(n.code,{children:"INFERBO_ALLOC_IS_BIG"})," on ",(0,r.jsx)(n.code,{children:"malloc(n)"}),"."]}),"\n",(0,r.jsx)(n.p,{children:"Action: Fix the size argument or make sure it is really needed."}),"\n",(0,r.jsx)(n.h2,{id:"inferbo_alloc_is_negative",children:"INFERBO_ALLOC_IS_NEGATIVE"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Alloc Is Negative" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-bufferoverrun",children:"bufferoverrun"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"malloc"})," is called with a negative size. For example, ",(0,r.jsx)(n.code,{children:"int n = 3 - 5; malloc(n);"})," generates ",(0,r.jsx)(n.code,{children:"INFERBO_ALLOC_IS_NEGATIVE"})," on ",(0,r.jsx)(n.code,{children:"malloc(n)"}),"."]}),"\n",(0,r.jsx)(n.p,{children:"Action: Fix the size argument."}),"\n",(0,r.jsx)(n.h2,{id:"inferbo_alloc_is_zero",children:"INFERBO_ALLOC_IS_ZERO"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Alloc Is Zero" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-bufferoverrun",children:"bufferoverrun"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"malloc"})," is called with a zero size. For example, ",(0,r.jsx)(n.code,{children:"int n = 3 - 3; malloc(n);"})," generates ",(0,r.jsx)(n.code,{children:"INFERBO_ALLOC_IS_ZERO"})," on ",(0,r.jsx)(n.code,{children:"malloc(n)"}),"."]}),"\n",(0,r.jsx)(n.p,{children:"Action: Fix the size argument."}),"\n",(0,r.jsx)(n.h2,{id:"inferbo_alloc_may_be_big",children:"INFERBO_ALLOC_MAY_BE_BIG"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Alloc May Be Big" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-bufferoverrun",children:"bufferoverrun"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"malloc"})," ",(0,r.jsx)(n.em,{children:"may"})," be called with a large value. For example, ",(0,r.jsx)(n.code,{children:"int n = b ? 3 : 1000000; malloc(n);"})," generates ",(0,r.jsx)(n.code,{children:"INFERBO_ALLOC_MAY_BE_BIG"})," on ",(0,r.jsx)(n.code,{children:"malloc(n)"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["Action: Fix the size argument or add a bound checking, e.g. ",(0,r.jsx)(n.code,{children:"if (n < A_SMALL_NUMBER) { malloc(n); }"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"inferbo_alloc_may_be_negative",children:"INFERBO_ALLOC_MAY_BE_NEGATIVE"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Alloc May Be Negative" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-bufferoverrun",children:"bufferoverrun"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"malloc"})," ",(0,r.jsx)(n.em,{children:"may"})," be called with a negative value. For example, ",(0,r.jsx)(n.code,{children:"int n = b ? 3 : -5; malloc(n);"})," generates ",(0,r.jsx)(n.code,{children:"INFERBO_ALLOC_MAY_BE_NEGATIVE"})," on ",(0,r.jsx)(n.code,{children:"malloc(n)"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["Action: Fix the size argument or add a bound checking, e.g. ",(0,r.jsx)(n.code,{children:"if (n > 0) { malloc(n); }"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"infinite_execution_time",children:"INFINITE_EXECUTION_TIME"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Infinite Execution Time" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-cost",children:"cost"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"This warning indicates that Infer was not able to determine a static\nupper bound on the execution cost of the procedure. By default, this\nissue type is disabled."}),"\n",(0,r.jsx)(n.h3,{id:"example-1-t-due-to-expressivity",children:"Example 1: T due to expressivity"}),"\n",(0,r.jsx)(n.p,{children:"For instance, Inferbo's interval analysis is limited to affine\nexpressions. Hence, we can't statically estimate an upper bound on the\nbelow example and obtain T(unknown) cost:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"// Expected: square root(x), got T\nvoid square_root_FP(int x) {\n int i = 0;\n while (i * i < x) {\n i++;\n }\n}\n"})}),"\n",(0,r.jsx)(n.h3,{id:"example-2-t-due-to-unmodeled-calls",children:"Example 2: T due to unmodeled calls"}),"\n",(0,r.jsx)(n.p,{children:"Another common case where we get T cost is when Infer cannot statically determine the range of values for loop bounds. For instance,"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"void loop_over_charArray_FP(StringBuilder builder, String input) {\n for (Character c : input.toCharArray()) {}\n}\n"})}),"\n",(0,r.jsxs)(n.p,{children:["Here, Infer does not have any InferBo models for the range of values returned by ",(0,r.jsx)(n.code,{children:"String.toCharArray"}),", hence it cannot determine that we will be iterating over a char array in the size of ",(0,r.jsx)(n.code,{children:"input"})," string."]}),"\n",(0,r.jsxs)(n.p,{children:["To teach InferBo about such library calls, they should be semantically modeled in ",(0,r.jsx)(n.a,{href:"https://github.com/facebook/infer/blob/main/infer/src/bufferoverrun/bufferOverrunModels.ml",children:"InferBo"}),"."]}),"\n",(0,r.jsx)(n.h3,{id:"example-3-t-due-to-calling-another-t-costed-function",children:"Example 3: T due to calling another T-costed function"}),"\n",(0,r.jsx)(n.p,{children:"Since the analysis is inter-procedural, another example we can have T cost is if at least one of the callees has T cost."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"// Expected: constant, got T\nvoid call_top_cost_FP() {\n square_root_FP(1); // square_root_FP has Top cost\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"infinite_recursion",children:"INFINITE_RECURSION"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "Infinite Recursion" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A special case of ",(0,r.jsx)(n.a,{href:"#mutual_recursion_cycle",children:"MUTUAL_RECURSION_CYCLE"})," where we detected that the recursive call is made with the exact same values, which guarantees an infinite recursion."]}),"\n",(0,r.jsx)(n.h2,{id:"integer_overflow_l1",children:"INTEGER_OVERFLOW_L1"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Integer Overflow L1" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-bufferoverrun",children:"bufferoverrun"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This is reported when integer overflow occurred by integer operations such as addition, subtraction,\nand multiplication. For example, ",(0,r.jsx)(n.code,{children:"int n = INT_MAX; int m = n + 3;"})," generates a INTEGER_OVERFLOW_L1\non ",(0,r.jsx)(n.code,{children:"n + 3"}),"."]}),"\n",(0,r.jsx)(n.p,{children:'Integer overflows reports fall into several "buckets" corresponding to the expected precision of the\nreport. The higher the number, the more likely it is to be a false positive.'}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"L1"}),": The most faithful report, when it ",(0,r.jsx)(n.em,{children:"must"})," be unsafe. For example,\n",(0,r.jsx)(n.code,{children:"[2147483647,2147483647] + [1,1]"})," in 32-bit signed integer type."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"L2"}),": Less faithful report than ",(0,r.jsx)(n.code,{children:"L1"}),", when it ",(0,r.jsx)(n.em,{children:"may"})," be unsafe. For example,\n",(0,r.jsx)(n.code,{children:"[2147483647,2147483647] + [0,1]"})," in 32-bit signed integer type. Note that the integer of RHS\ncan be 0, which is safe."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"L5"}),": The reports that are not included in the above cases."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"U5"}),": A binary integer operation is unsafe by unknown values, which are usually from unknown\nfunction calls."]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"integer_overflow_l2",children:"INTEGER_OVERFLOW_L2"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Integer Overflow L2" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-bufferoverrun",children:"bufferoverrun"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["See ",(0,r.jsx)(n.a,{href:"#integer_overflow_l1",children:"INTEGER_OVERFLOW_L1"})]}),"\n",(0,r.jsx)(n.h2,{id:"integer_overflow_l5",children:"INTEGER_OVERFLOW_L5"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Integer Overflow L5" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-bufferoverrun",children:"bufferoverrun"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["See ",(0,r.jsx)(n.a,{href:"#integer_overflow_l1",children:"INTEGER_OVERFLOW_L1"})]}),"\n",(0,r.jsx)(n.h2,{id:"integer_overflow_u5",children:"INTEGER_OVERFLOW_U5"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Integer Overflow U5" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-bufferoverrun",children:"bufferoverrun"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["See ",(0,r.jsx)(n.a,{href:"#integer_overflow_l1",children:"INTEGER_OVERFLOW_L1"})]}),"\n",(0,r.jsx)(n.h2,{id:"interface_not_thread_safe",children:"INTERFACE_NOT_THREAD_SAFE"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#concurrency",children:"Concurrency"}),'. Reported as "Interface Not Thread Safe" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-racerd",children:"racerd"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This error indicates that you have invoked an interface method not annotated\nwith ",(0,r.jsx)(n.code,{children:"@ThreadSafe"})," from a thread-safe context (e.g., code that uses locks or is\nmarked ",(0,r.jsx)(n.code,{children:"@ThreadSafe"}),"). The fix is to add the ",(0,r.jsx)(n.code,{children:"@ThreadSafe"})," annotation to the\ninterface or to the interface method. For background on why these annotations\nare needed, see the detailed explanation\n",(0,r.jsx)(n.a,{href:"/docs/next/checker-racerd#interface-not-thread-safe",children:"here"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"invalid_sil",children:"INVALID_SIL"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Invalid Sil" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-sil-validation",children:"sil-validation"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"The SIL instruction does not conform to the expected subset of instructions\nexpected for the front-end of the language for the analyzed code."}),"\n",(0,r.jsx)(n.h2,{id:"invariant_call",children:"INVARIANT_CALL"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Invariant Call" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-loop-hoisting",children:"loop-hoisting"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"We report this issue type when a function call is loop-invariant and hoistable, i.e."}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"the function has no side side effects (pure)"}),"\n",(0,r.jsx)(n.li,{children:"has invariant arguments and result (i.e. have the same value in all loop iterations)"}),"\n",(0,r.jsx)(n.li,{children:"it is guaranteed to execute, i.e. it dominates all loop sources"}),"\n"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"int foo(int x, int y) {\n return x + y;\n}\n\n\nvoid invariant_hoist(int size) {\n int x = 10;\n int y = 5;\n for (int i = 0; i < size; i++) {\n foo(x, y); // hoistable\n }\n }\n"})}),"\n",(0,r.jsx)(n.h2,{id:"ipc_on_ui_thread",children:"IPC_ON_UI_THREAD"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#perf-regression",children:"Perf regression"}),'. Reported as "Ipc On Ui Thread" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-starvation",children:"starvation"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A blocking ",(0,r.jsx)(n.code,{children:"Binder"})," IPC call occurs on the UI thread."]}),"\n",(0,r.jsx)(n.h2,{id:"lab_resource_leak",children:"LAB_RESOURCE_LEAK"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Lab Resource Leak" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-resource-leak-lab",children:"resource-leak-lab"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"Toy issue."}),"\n",(0,r.jsx)(n.h2,{id:"lineage_flow",children:"LINEAGE_FLOW"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#sensitive-data-flow",children:"Sensitive data flow"}),'. Reported as "Lineage Flow" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-lineage",children:"lineage"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"A Lineage taint flow has been detected from a source to a sink."}),"\n",(0,r.jsx)(n.h2,{id:"lockless_violation",children:"LOCKLESS_VIOLATION"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Lockless Violation" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-starvation",children:"starvation"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A method implements an interface signature annotated with ",(0,r.jsx)(n.code,{children:"@Lockless"})," but which transitively acquires a lock."]}),"\n",(0,r.jsx)(n.p,{children:"Example:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"Interface I {\n @Lockless\n public void no_lock();\n}\n\nclass C implements I {\n private synchronized do_lock() {}\n\n public void no_lock() { // this method should not acquire any locks\n do_lock();\n }\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"lock_consistency_violation",children:"LOCK_CONSISTENCY_VIOLATION"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#concurrency",children:"Concurrency"}),'. Reported as "Lock Consistency Violation" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-racerd",children:"racerd"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"This is an error reported on C++ and Objective C classes whenever:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Some class method directly uses locking primitives (not transitively)."}),"\n",(0,r.jsxs)(n.li,{children:["It has a public method which writes to some member ",(0,r.jsx)(n.code,{children:"x"})," while holding a lock."]}),"\n",(0,r.jsxs)(n.li,{children:["It has a public method which reads ",(0,r.jsx)(n.code,{children:"x"})," without holding a lock."]}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:["The above may happen through a chain of calls. Above, ",(0,r.jsx)(n.code,{children:"x"})," may also be a\ncontainer (an array, a vector, etc)."]}),"\n",(0,r.jsx)(n.h3,{id:"fixing-lock-consistency-violation-reports",children:"Fixing Lock Consistency Violation reports"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Avoid the offending access (most often the read). Of course, this may not be\npossible."}),"\n",(0,r.jsx)(n.li,{children:"Use synchronization to protect the read, by using the same lock protecting the\ncorresponding write."}),"\n",(0,r.jsx)(n.li,{children:"Make the method doing the read access private. This should silence the\nwarning, since Infer looks for a pair of non-private methods. Objective-C:\nInfer considers a method as private if it's not exported in the header-file\ninterface."}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"lock_on_ui_thread",children:"LOCK_ON_UI_THREAD"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#perf-regression",children:"Perf regression"}),'. Reported as "Lock on UI Thread" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-starvation",children:"starvation"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"A method annoted as being on UIThread acquires a lock. This could be a potential performance issue"}),"\n",(0,r.jsx)(n.p,{children:"Example:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"class Example {\n @UiThread\n void foo() {\n synchronized(this) {\n }\n }\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"memory_leak_c",children:"MEMORY_LEAK_C"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#resource-leak",children:"Resource leak"}),'. Reported as "Memory Leak" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsx)(n.h3,{id:"memory-leak-in-c",children:"Memory leak in C"}),"\n",(0,r.jsx)(n.p,{children:"This error type is only reported in C and Objective-C code. In Java we do not\nreport memory leaks because it is a garbage collected language."}),"\n",(0,r.jsxs)(n.p,{children:["In C, Infer reports memory leaks when objects are created with ",(0,r.jsx)(n.code,{children:"malloc"})," and not\nfreed. For example:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-c",children:"-(void) memory_leak_bug {\n struct Person *p = malloc(sizeof(struct Person));\n}\n"})}),"\n",(0,r.jsx)(n.h3,{id:"memory-leak-in-objective-c",children:"Memory leak in Objective-C"}),"\n",(0,r.jsx)(n.p,{children:"Additionally, in Objective-C, Infer reports memory leaks that happen when\nobjects from Core Foundation or Core Graphics don't get released."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objectivec",children:"-(void) memory_leak_bug_cf {\n CGPathRef shadowPath = CGPathCreateWithRect(self.inputView.bounds, NULL); //object created and not released.\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"memory_leak_cpp",children:"MEMORY_LEAK_CPP"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#resource-leak",children:"Resource leak"}),'. Reported as "Memory Leak" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["See ",(0,r.jsx)(n.a,{href:"#memory_leak_c",children:"MEMORY_LEAK_C"})]}),"\n",(0,r.jsx)(n.h2,{id:"missing_required_prop",children:"MISSING_REQUIRED_PROP"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "Missing Required Prop" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-litho-required-props",children:"litho-required-props"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This issues is reported when a required ",(0,r.jsx)(n.code,{children:"@Prop"})," is missing."]}),"\n",(0,r.jsx)(n.h2,{id:"examples",children:"Examples"}),"\n",(0,r.jsxs)(n.p,{children:["Assume that the following Litho Component specification is defined as follows where ",(0,r.jsx)(n.code,{children:"prop1"})," is optional and ",(0,r.jsx)(n.code,{children:"prop2"})," is required."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"class MyComponentSpec {\n\n static void onCreate(\n ComponentContext c,\n @Prop(optional = true) String prop1, @Prop int prop2) {\n ...\n }\n ...\n}\n"})}),"\n",(0,r.jsxs)(n.p,{children:["When we build the corresponding component, we should have all the required props. If we are missing optional props (e..g ",(0,r.jsx)(n.code,{children:"prop1"})," below), it is ok."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"MyComponent.create(c)\n .prop2(8)\n .build();\n"})}),"\n",(0,r.jsxs)(n.p,{children:["However, if we are missing a required prop, Infer gives an error below for the missing ",(0,r.jsx)(n.code,{children:"prop2"}),"."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:'MyComponent.create(c)\n .prop1("My prop 1")\n .build();\n'})}),"\n",(0,r.jsx)(n.p,{children:"** Action **"}),"\n",(0,r.jsx)(n.p,{children:"There are two ways to fix this issue."}),"\n",(0,r.jsxs)(n.p,{children:["First, we could add the missing ",(0,r.jsx)(n.code,{children:"prop2"}),":"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:'MyComponent.create(c)\n .prop1("My prop 1")\n .prop2(x) // where x is some integer\n .build();\n'})}),"\n",(0,r.jsxs)(n.p,{children:["or alternatively, if the ",(0,r.jsx)(n.code,{children:"prop2"})," is not really required, we could change the component spec to reflect that:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"class MyComponentSpec {\n\n static void onCreate(\n ComponentContext c,\n @Prop(optional = true) String prop1, @Prop(optional = true) int prop2) {\n ...\n }\n ...\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"mixed_self_weakself",children:"MIXED_SELF_WEAKSELF"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#resource-leak",children:"Resource leak"}),'. Reported as "Mixed Self WeakSelf" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-self-in-block",children:"self-in-block"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This check reports an issue when an Objective-C block captures both ",(0,r.jsx)(n.code,{children:"self"})," and ",(0,r.jsx)(n.code,{children:"weakSelf"}),", a weak pointer to ",(0,r.jsx)(n.code,{children:"self"}),".\nPossibly the developer meant to capture only ",(0,r.jsx)(n.code,{children:"weakSelf"})," to avoid a retain cycle, but made a typo and used ",(0,r.jsx)(n.code,{children:"self"}),"\ninstead of ",(0,r.jsx)(n.code,{children:"strongSelf"}),". In this case, this could cause a retain cycle."]}),"\n",(0,r.jsx)(n.p,{children:"Example:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objectivec",children:" __weak __typeof(self) weakSelf = self;\n int (^my_block)() = ^() {\n __strong __typeof(weakSelf) strongSelf = weakSelf;\n if (strongSelf) {\n [strongSelf foo];\n int x = self->x; // typo here\n }\n return 0;\n };\n"})}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"Action"}),": Fixing the typo is generally the right course of action."]}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.em,{children:"Limitations:"})," To keep this check simple and intra-procedural, we rely on names to find ",(0,r.jsx)(n.code,{children:"weakSelf"}),':\nwe assume that any captured weak pointer whose name contains "self" is a weak reference to ',(0,r.jsx)(n.code,{children:"self"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"modifies_immutable",children:"MODIFIES_IMMUTABLE"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Modifies Immutable" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-impurity",children:"impurity"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This issue type indicates modifications to fields marked as @Immutable. For instance, below function ",(0,r.jsx)(n.code,{children:"mutateArray"})," would be marked as modifying immutable field ",(0,r.jsx)(n.code,{children:"testArray"}),":"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:" @Immutable int[] testArray = new int[]{0, 1, 2, 4};\n \n int[] getTestArray() {\n return testArray;\n } \n \n void mutateArray() {\n int[] array = getTestArray();\n array[2] = 7;\n }\n"})}),"\n",(0,r.jsx)(n.h2,{id:"multiple_weakself",children:"MULTIPLE_WEAKSELF"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Multiple WeakSelf Use" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-self-in-block",children:"self-in-block"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This check reports when an Objective-C block uses ",(0,r.jsx)(n.code,{children:"weakSelf"})," (a weak pointer to ",(0,r.jsx)(n.code,{children:"self"}),") more than once.\nThis could lead to unexpected behaviour. Even if ",(0,r.jsx)(n.code,{children:"weakSelf"})," is not nil in the first use, it could be nil\nin the following uses since the object that ",(0,r.jsx)(n.code,{children:"weakSelf"})," points to could be freed anytime."]}),"\n",(0,r.jsx)(n.p,{children:"Example:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objectivec",children:" __weak __typeof(self) weakSelf = self;\n int (^my_block)() = ^() {\n [weakSelf foo];\n int x = weakSelf->x;\n };\n"})}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"Action:"}),"\nOne should assign ",(0,r.jsx)(n.code,{children:"weakSelf"})," to a strong pointer first, and then\nuse it in the block."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objectivec",children:" __weak __typeof(self) weakSelf = self;\n int (^my_block)() = ^() {\n __strong __typeof(weakSelf) strongSelf = weakSelf;\n if (strongSelf) {\n [strongSelf foo];\n int x = strongSelf->x;\n }\n ...\n };\n"})}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.em,{children:"Limitations:"})," To keep this check simple and intra-procedural, we rely on names to find ",(0,r.jsx)(n.code,{children:"weakSelf"}),':\nwe assume that any captured weak pointer whose name contains "self" is a weak reference to ',(0,r.jsx)(n.code,{children:"self"}),".\nIn contrast, ",(0,r.jsx)(n.code,{children:"strongSelf"})," is a local variable to the block, so the check supports any name given to\na local strong pointer that has been assigned ",(0,r.jsx)(n.code,{children:"weakSelf"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"mutual_recursion_cycle",children:"MUTUAL_RECURSION_CYCLE"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "Mutual Recursion Cycle" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A recursive call or mutually recursive call has been detected. This does ",(0,r.jsx)(n.em,{children:"not"})," mean that the program won't terminate, just that the code is recursive. You should double-check if the recursion is intended and if it can lead to non-termination or a stack overflow."]}),"\n",(0,r.jsx)(n.p,{children:"Example of recursive function:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-C",children:"int factorial(int x) {\n if (x > 0) {\n return x * factorial(x-1);\n } else {\n return 1;\n }\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"nil_block_call",children:"NIL_BLOCK_CALL"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#null-pointer-dereference",children:"Null pointer dereference"}),'. Reported as "Nil Block Call" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This check reports when one tries to call an Objective-C block that is ",(0,r.jsx)(n.code,{children:"nil"}),".\nThis causes a crash."]}),"\n",(0,r.jsx)(n.p,{children:"Example:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objectivec",children:"-(void) foo:(void (^)())callback {\n callback();\n}\n\n-(void) bar {\n [self foo:nil]; //crash\n}\n"})}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"Action"}),":"]}),"\n",(0,r.jsxs)(n.p,{children:["Adding a check for ",(0,r.jsx)(n.code,{children:"nil"})," before calling the block, or making sure never to call the method ",(0,r.jsx)(n.code,{children:"foo:"})," with ",(0,r.jsx)(n.code,{children:"nil"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"nil_block_call_latent",children:"NIL_BLOCK_CALL_LATENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#null-pointer-dereference",children:"Null pointer dereference"}),'. Reported as "Nil Block Call Latent" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A latent ",(0,r.jsx)(n.a,{href:"#nil_block_call",children:"NIL_BLOCK_CALL"}),". See the ",(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse#latent-issues",children:"documentation on Pulse latent issues"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"nil_insertion_into_collection",children:"NIL_INSERTION_INTO_COLLECTION"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "Nil Insertion Into Collection" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This checks reports when ",(0,r.jsx)(n.code,{children:"nil"})," is passed to collections in Objective-C such as arrays and dictionaries. This causes a crash."]}),"\n",(0,r.jsx)(n.h3,{id:"arrays",children:"Arrays"}),"\n",(0,r.jsxs)(n.p,{children:["Adding objects to an array, inserting objects at a given index, or replacing objects at a given index, can all\nlead to a crash when the object is ",(0,r.jsx)(n.code,{children:"nil"}),"."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objectivec",children:" [mArray addObject:nil]; //crash\n\n [mArray insertObject:nil atIndex:0]; //crash\n\n [mArray replaceObjectAtIndex:0 withObject:nil]; //crash\n"})}),"\n",(0,r.jsx)(n.h3,{id:"dictionaries",children:"Dictionaries"}),"\n",(0,r.jsxs)(n.p,{children:["Adding a ",(0,r.jsx)(n.code,{children:"nil"})," value in a dictionary causes a crash. If the concept of ",(0,r.jsx)(n.code,{children:"nil"})," is required, one can add\n",(0,r.jsx)(n.code,{children:"[NSNull null]"})," instead."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objectivec",children:' id value = nil;\n [mDict setObject:value forKey:@"somestring"]; //crash\n\n [mDict setObject:[NSNull null] forKey:@"somestring"]; //ok\n'})}),"\n",(0,r.jsxs)(n.p,{children:["Retrieving or removing an object from a dictionary with a ",(0,r.jsx)(n.code,{children:"nil"})," key also causes a crash:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objectivec",children:' id key = nil;\n mDict[key] = @"somestring"; //crash\n\n [mDict removeObjectForKey:nil]; //crash\n'})}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"Action"}),":"]}),"\n",(0,r.jsxs)(n.p,{children:["In all the cases above, when passing ",(0,r.jsx)(n.code,{children:"nil"})," causes a crash, the solutions are either making sure\nthat the object passed will never be ",(0,r.jsx)(n.code,{children:"nil"}),", or adding a check for ",(0,r.jsx)(n.code,{children:"nil"})," before calling those methods."]}),"\n",(0,r.jsx)(n.h2,{id:"nil_insertion_into_collection_latent",children:"NIL_INSERTION_INTO_COLLECTION_LATENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "Nil Insertion Into Collection" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A latent ",(0,r.jsx)(n.a,{href:"#nil_insertion_into_collection",children:"NIL_INSERTION_INTO_COLLECTION"}),". See the ",(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse#latent-issues",children:"documentation on Pulse latent issues"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"nil_messaging_to_non_pod",children:"NIL_MESSAGING_TO_NON_POD"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#memory-error",children:"Memory error"}),'. Reported as "Nil Messaging To Non Pod" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["In Objective-C, calling a method on ",(0,r.jsx)(n.code,{children:"nil"})," (or in Objective-C terms, sending a message to ",(0,r.jsx)(n.code,{children:"nil"}),") does not crash,\nit simply returns a falsy value (nil/0/false). However, sending a message that returns\na non-POD C++ type (POD being ",(0,r.jsx)(n.a,{href:"https://en.cppreference.com/w/cpp/named_req/PODType",children:'"Plain Old Data"'}),", essentially\nanything that cannot be compiled as a C-style struct) to ",(0,r.jsx)(n.code,{children:"nil"})," causes undefined behaviour."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objectivec",children:"std::shared_ptr callMethodReturnsnonPOD() {\n SomeObject* obj = getObjectOrNil();\n std::shared_ptr d = [obj returnsnonPOD]; // UB\n return d;\n}\n"})}),"\n",(0,r.jsxs)(n.p,{children:["To fix the above issue, we need to check if ",(0,r.jsx)(n.code,{children:"obj"})," is\nnot ",(0,r.jsx)(n.code,{children:"nil"})," before calling the ",(0,r.jsx)(n.code,{children:"returnsnonPOD"})," method:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objectivec",children:"std::shared_ptr callMethodReturnsnonPOD(bool b) {\n SomeObject* obj = getObjectOrNil(b);\n if (obj == nil) { return std::make_shared(0); }\n std::shared_ptr d = [obj returnsnonPOD];\n return d;\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"nil_messaging_to_non_pod_latent",children:"NIL_MESSAGING_TO_NON_POD_LATENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#memory-error",children:"Memory error"}),'. Reported as "Nil Messaging To Non Pod Latent" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A latent ",(0,r.jsx)(n.a,{href:"#nil_messaging_to_non_pod",children:"NIL_MESSAGING_TO_NON_POD"}),". See the ",(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse#latent-issues",children:"documentation on Pulse latent issues"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"no_matching_branch_in_try",children:"NO_MATCHING_BRANCH_IN_TRY"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "No Matching Branch In Try" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["No matching branch is found when evaluating the ",(0,r.jsx)(n.code,{children:"of"})," section of a ",(0,r.jsx)(n.code,{children:"try"})," expression. Corresponds to the ",(0,r.jsx)(n.code,{children:"{try_clause,V}"})," error in the Erlang runtime."]}),"\n",(0,r.jsxs)(n.p,{children:["For example, if we call ",(0,r.jsx)(n.code,{children:"tail([])"})," and the full definition of ",(0,r.jsx)(n.code,{children:"tail"})," is"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-erlang",children:"tail(X) ->\n try X of\n [_|T] -> {ok,T}\n catch\n _ -> error\n end.\n"})}),"\n",(0,r.jsx)(n.h2,{id:"no_matching_branch_in_try_latent",children:"NO_MATCHING_BRANCH_IN_TRY_LATENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "No Matching Branch In Try Latent" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A latent ",(0,r.jsx)(n.a,{href:"#no_matching_branch_in_try",children:"NO_MATCHING_BRANCH_IN_TRY"}),". See the ",(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse#latent-issues",children:"documentation on Pulse latent issues"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"no_matching_case_clause",children:"NO_MATCHING_CASE_CLAUSE"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "No Matching Case Clause" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["No matching case clause in Erlang: Reports an error when none of the clauses of a ",(0,r.jsx)(n.code,{children:"case"})," match the expression. Corresponds to the ",(0,r.jsx)(n.code,{children:"{case_clause,V}"})," error in the Erlang runtime."]}),"\n",(0,r.jsxs)(n.p,{children:["For example, if we call ",(0,r.jsx)(n.code,{children:"tail([])"})," and the full definition of ",(0,r.jsx)(n.code,{children:"tail"})," is"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-erlang",children:"tail(X) ->\n case X of\n [_|T] -> T\n end.\n"})}),"\n",(0,r.jsx)(n.p,{children:"This error is reported if either the pattern(s) or the guard(s) prevent matching any of the clauses."}),"\n",(0,r.jsx)(n.h2,{id:"no_matching_case_clause_latent",children:"NO_MATCHING_CASE_CLAUSE_LATENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "No Matching Case Clause Latent" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A latent ",(0,r.jsx)(n.a,{href:"#no_matching_case_clause",children:"NO_MATCHING_CASE_CLAUSE"}),". See the ",(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse#latent-issues",children:"documentation on Pulse latent issues"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"no_matching_else_clause",children:"NO_MATCHING_ELSE_CLAUSE"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "No Matching Else Clause" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["No matching else clause in Erlang: Reports an error when none of the clauses of an ",(0,r.jsx)(n.code,{children:"else"})," match the short-circuit result from ",(0,r.jsx)(n.code,{children:"maybe"})," body. Corresponds to the ",(0,r.jsx)(n.code,{children:"{else_clause,V}"})," error in the Erlang runtime."]}),"\n",(0,r.jsxs)(n.p,{children:["For example, here the ",(0,r.jsx)(n.code,{children:"1 ?= 2"})," expression does not match and short-circuits to ",(0,r.jsx)(n.code,{children:"2"}),", which does not match the single clause under ",(0,r.jsx)(n.code,{children:"else"}),":"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-erlang",children:"else_clause_error() ->\n maybe\n 1 ?= 2\n else\n 1 -> ok\n end.\n"})}),"\n",(0,r.jsx)(n.p,{children:"This error is reported if either the pattern(s) or the guard(s) prevent matching any of the clauses."}),"\n",(0,r.jsx)(n.h2,{id:"no_matching_else_clause_latent",children:"NO_MATCHING_ELSE_CLAUSE_LATENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "No Matching Else Clause Latent" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A latent ",(0,r.jsx)(n.a,{href:"#no_matching_else_clause",children:"NO_MATCHING_ELSE_CLAUSE"}),". See the ",(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse#latent-issues",children:"documentation on Pulse latent issues"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"no_matching_function_clause",children:"NO_MATCHING_FUNCTION_CLAUSE"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "No Matching Function Clause" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["No matching function clause in Erlang: Reports an error when none of the clauses of a function match the arguments of a call. Corresponds to the ",(0,r.jsx)(n.code,{children:"function_clause"})," error in the Erlang runtime."]}),"\n",(0,r.jsxs)(n.p,{children:["For example, if we call ",(0,r.jsx)(n.code,{children:"tail([])"})," and the full definition of ",(0,r.jsx)(n.code,{children:"tail"})," is"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-erlang",children:"tail([_|Xs]) -> Xs.\n"})}),"\n",(0,r.jsx)(n.p,{children:"This error is reported if either the pattern(s) or the guard(s) prevent matching any of the clauses."}),"\n",(0,r.jsx)(n.h2,{id:"no_matching_function_clause_latent",children:"NO_MATCHING_FUNCTION_CLAUSE_LATENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "No Matching Function Clause Latent" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A latent ",(0,r.jsx)(n.a,{href:"#no_matching_function_clause",children:"NO_MATCHING_FUNCTION_CLAUSE"}),". See the ",(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse#latent-issues",children:"documentation on Pulse latent issues"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"no_match_of_rhs",children:"NO_MATCH_OF_RHS"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "No Match Of Rhs" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["No match of right hand side value in Erlang: Reports an error when the right hand side value of a ",(0,r.jsx)(n.code,{children:"match"})," expression does not match the pattern on the left hand side. Corresponds to the ",(0,r.jsx)(n.code,{children:"{badmatch,V}"})," error in the Erlang runtime."]}),"\n",(0,r.jsxs)(n.p,{children:["For example, ",(0,r.jsx)(n.code,{children:"[H|T] = []"})," gives the error because the left hand side pattern requires at least one element in the list on the right hand side."]}),"\n",(0,r.jsx)(n.h2,{id:"no_match_of_rhs_latent",children:"NO_MATCH_OF_RHS_LATENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "No Match Of Rhs Latent" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A latent ",(0,r.jsx)(n.a,{href:"#no_match_of_rhs",children:"NO_MATCH_OF_RHS"}),". See the ",(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse#latent-issues",children:"documentation on Pulse latent issues"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"no_true_branch_in_if",children:"NO_TRUE_BRANCH_IN_IF"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "No True Branch In If" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["No true branch when evaluating an if expression in Erlang: Reports an error when none of the branches of an ",(0,r.jsx)(n.code,{children:"if"})," expression evaluate to true. Corresponds to the ",(0,r.jsx)(n.code,{children:"if_clause"})," error in the Erlang runtime."]}),"\n",(0,r.jsxs)(n.p,{children:["For example, if we call ",(0,r.jsx)(n.code,{children:"sign(0)"})," and the full definition of ",(0,r.jsx)(n.code,{children:"sign"})," is"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-erlang",children:"sign(X) ->\n if\n X > 0 -> positive;\n X < 0 -> negative\n end.\n"})}),"\n",(0,r.jsx)(n.h2,{id:"no_true_branch_in_if_latent",children:"NO_TRUE_BRANCH_IN_IF_LATENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "No True Branch In If Latent" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A latent ",(0,r.jsx)(n.a,{href:"#no_true_branch_in_if",children:"NO_TRUE_BRANCH_IN_IF"}),". See the ",(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse#latent-issues",children:"documentation on Pulse latent issues"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"nsstring_internal_ptr_captured_in_block",children:"NSSTRING_INTERNAL_PTR_CAPTURED_IN_BLOCK"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#memory-error",children:"Memory error"}),'. Reported as "NSString Captured in Block" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-self-in-block",children:"self-in-block"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This check flags when an internal pointer of a local variable of type ",(0,r.jsx)(n.code,{children:"std::string"})," is captured in an escaping block.\nThis means that the block will be leaving the current scope, i.e. it is\nnot annotated with ",(0,r.jsx)(n.code,{children:"__attribute__((noescape))"}),"."]}),"\n",(0,r.jsx)(n.p,{children:"Example:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:" std::string fullName;\n const char* c = fullName.c_str();\n dispatch_async(dispatch_get_main_queue(), ^{\n const char* c1 = c;\n });\n"})}),"\n",(0,r.jsx)(n.p,{children:"This could cause crashes because the variable is likely to be freed when the code is executed, leaving the pointer dangling."}),"\n",(0,r.jsx)(n.h2,{id:"nullptr_dereference",children:"NULLPTR_DEREFERENCE"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#null-pointer-dereference",children:"Null pointer dereference"}),'. Reported as "Null Dereference" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"Infer reports null dereference bugs in Java, C, C++, and Objective-C\nwhen it is possible that the null pointer is dereferenced, leading to\na crash."}),"\n",(0,r.jsx)(n.h3,{id:"null-dereference-in-java",children:"Null dereference in Java"}),"\n",(0,r.jsx)(n.p,{children:"Many of Infer's reports of potential Null Pointer Exceptions (NPE) come from code of the form"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:" p = foo(); // foo() might return null\n stuff();\n p.goo(); // dereferencing p, potential NPE\n"})}),"\n",(0,r.jsx)(n.p,{children:"If you see code of this form, then you have several options."}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsxs)(n.strong,{children:["If you are unsure whether or not ",(0,r.jsx)(n.code,{children:"foo()"})," will return null"]}),", you should\nideally either"]}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["Change the code to ensure that ",(0,r.jsx)(n.code,{children:"foo()"})," can not return null, or"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["Add a check that ",(0,r.jsx)(n.code,{children:"p"})," is not ",(0,r.jsx)(n.code,{children:"null"})," before dereferencing ",(0,r.jsx)(n.code,{children:"p"}),"."]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:["Sometimes, in case (2) it is not obvious what you should do when ",(0,r.jsx)(n.code,{children:"p"}),"\nis ",(0,r.jsx)(n.code,{children:"null"}),". One possibility is to throw an exception, failing early but\nexplicitly. This can be done using ",(0,r.jsx)(n.code,{children:"checkNotNull"})," as in the following\ncode:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"// code idiom for failing early\nimport static com.google.common.base.Preconditions.checkNotNull;\n\n //... intervening code\n\n p = checkNotNull(foo()); // foo() might return null\n stuff();\n p.goo(); // p cannot be null here\n"})}),"\n",(0,r.jsxs)(n.p,{children:["The call ",(0,r.jsx)(n.code,{children:"checkNotNull(foo())"})," will never return ",(0,r.jsx)(n.code,{children:"null"}),": if ",(0,r.jsx)(n.code,{children:"foo()"}),"\nreturns ",(0,r.jsx)(n.code,{children:"null"})," then it fails early by throwing a Null Pointer\nException."]}),"\n",(0,r.jsxs)(n.p,{children:["Facebook NOTE: ",(0,r.jsx)(n.strong,{children:"If you are absolutely sure that foo() will not be\nnull"}),", then if you land your diff this case will no longer be\nreported after your diff makes it to trunk."]}),"\n",(0,r.jsx)(n.h3,{id:"null-dereference-in-c",children:"Null dereference in C"}),"\n",(0,r.jsx)(n.p,{children:"Here is an example of an inter-procedural null dereference bug in C:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-c",children:"struct Person {\n int age;\n int height;\n int weight;\n};\nint get_age(struct Person *who) {\n return who->age;\n}\nint null_pointer_interproc() {\n struct Person *joe = 0;\n return get_age(joe);\n}\n"})}),"\n",(0,r.jsx)(n.h3,{id:"null-dereference-in-objective-c",children:"Null dereference in Objective-C"}),"\n",(0,r.jsxs)(n.p,{children:["In Objective-C, null dereferences are less common than in Java, but they still\nhappen and their cause can be hidden. In general, passing a message to nil does\nnot cause a crash and returns ",(0,r.jsx)(n.code,{children:"nil"}),", but dereferencing a pointer directly does\ncause a crash."]}),"\n",(0,r.jsx)(n.p,{children:"Example:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objectivec",children:"(int) foo:(C*) param { // passing nil\n D* d = [param bar]; // nil message passing\n return d->fld; // crash\n}\n(void) callFoo {\n C* c = [self bar]; // returns nil\n [foo:c]; // crash reported here\n}\n"})}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"Action"}),":\nAdding a ",(0,r.jsx)(n.code,{children:"nil"})," check either for ",(0,r.jsx)(n.code,{children:"param"})," above or for ",(0,r.jsx)(n.code,{children:"d"}),", or making sure that ",(0,r.jsx)(n.code,{children:"foo:"})," will never\nbe called with ",(0,r.jsx)(n.code,{children:"nil"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["Calling a ",(0,r.jsx)(n.code,{children:"nil"})," block will also cause a crash.\nWe have a dedicated issue type for this case: ",(0,r.jsx)(n.a,{href:"/docs/next/all-issue-types#nil_block_call",children:"Nil Block Call"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["Moreover, inserting ",(0,r.jsx)(n.code,{children:"nil"})," into a collection will cause a crash as well. We\nalso have a dedicated issue type for this case:\n",(0,r.jsx)(n.a,{href:"/docs/next/all-issue-types#nil_insertion_into_collection",children:"Nil Insertion Into Collection"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"nullptr_dereference_in_nullsafe_class",children:"NULLPTR_DEREFERENCE_IN_NULLSAFE_CLASS"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#null-pointer-dereference",children:"Null pointer dereference"}),'. Reported as "Null Dereference" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"Infer reports null dereference bugs in Java, C, C++, and Objective-C\nwhen it is possible that the null pointer is dereferenced, leading to\na crash."}),"\n",(0,r.jsx)(n.h3,{id:"null-dereference-in-java-1",children:"Null dereference in Java"}),"\n",(0,r.jsx)(n.p,{children:"Many of Infer's reports of potential Null Pointer Exceptions (NPE) come from code of the form"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:" p = foo(); // foo() might return null\n stuff();\n p.goo(); // dereferencing p, potential NPE\n"})}),"\n",(0,r.jsx)(n.p,{children:"If you see code of this form, then you have several options."}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsxs)(n.strong,{children:["If you are unsure whether or not ",(0,r.jsx)(n.code,{children:"foo()"})," will return null"]}),", you should\nideally either"]}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["Change the code to ensure that ",(0,r.jsx)(n.code,{children:"foo()"})," can not return null, or"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["Add a check that ",(0,r.jsx)(n.code,{children:"p"})," is not ",(0,r.jsx)(n.code,{children:"null"})," before dereferencing ",(0,r.jsx)(n.code,{children:"p"}),"."]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:["Sometimes, in case (2) it is not obvious what you should do when ",(0,r.jsx)(n.code,{children:"p"}),"\nis ",(0,r.jsx)(n.code,{children:"null"}),". One possibility is to throw an exception, failing early but\nexplicitly. This can be done using ",(0,r.jsx)(n.code,{children:"checkNotNull"})," as in the following\ncode:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"// code idiom for failing early\nimport static com.google.common.base.Preconditions.checkNotNull;\n\n //... intervening code\n\n p = checkNotNull(foo()); // foo() might return null\n stuff();\n p.goo(); // p cannot be null here\n"})}),"\n",(0,r.jsxs)(n.p,{children:["The call ",(0,r.jsx)(n.code,{children:"checkNotNull(foo())"})," will never return ",(0,r.jsx)(n.code,{children:"null"}),": if ",(0,r.jsx)(n.code,{children:"foo()"}),"\nreturns ",(0,r.jsx)(n.code,{children:"null"})," then it fails early by throwing a Null Pointer\nException."]}),"\n",(0,r.jsxs)(n.p,{children:["Facebook NOTE: ",(0,r.jsx)(n.strong,{children:"If you are absolutely sure that foo() will not be\nnull"}),", then if you land your diff this case will no longer be\nreported after your diff makes it to trunk."]}),"\n",(0,r.jsx)(n.h3,{id:"null-dereference-in-c-1",children:"Null dereference in C"}),"\n",(0,r.jsx)(n.p,{children:"Here is an example of an inter-procedural null dereference bug in C:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-c",children:"struct Person {\n int age;\n int height;\n int weight;\n};\nint get_age(struct Person *who) {\n return who->age;\n}\nint null_pointer_interproc() {\n struct Person *joe = 0;\n return get_age(joe);\n}\n"})}),"\n",(0,r.jsx)(n.h3,{id:"null-dereference-in-objective-c-1",children:"Null dereference in Objective-C"}),"\n",(0,r.jsxs)(n.p,{children:["In Objective-C, null dereferences are less common than in Java, but they still\nhappen and their cause can be hidden. In general, passing a message to nil does\nnot cause a crash and returns ",(0,r.jsx)(n.code,{children:"nil"}),", but dereferencing a pointer directly does\ncause a crash."]}),"\n",(0,r.jsx)(n.p,{children:"Example:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objectivec",children:"(int) foo:(C*) param { // passing nil\n D* d = [param bar]; // nil message passing\n return d->fld; // crash\n}\n(void) callFoo {\n C* c = [self bar]; // returns nil\n [foo:c]; // crash reported here\n}\n"})}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"Action"}),":\nAdding a ",(0,r.jsx)(n.code,{children:"nil"})," check either for ",(0,r.jsx)(n.code,{children:"param"})," above or for ",(0,r.jsx)(n.code,{children:"d"}),", or making sure that ",(0,r.jsx)(n.code,{children:"foo:"})," will never\nbe called with ",(0,r.jsx)(n.code,{children:"nil"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["Calling a ",(0,r.jsx)(n.code,{children:"nil"})," block will also cause a crash.\nWe have a dedicated issue type for this case: ",(0,r.jsx)(n.a,{href:"/docs/next/all-issue-types#nil_block_call",children:"Nil Block Call"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["Moreover, inserting ",(0,r.jsx)(n.code,{children:"nil"})," into a collection will cause a crash as well. We\nalso have a dedicated issue type for this case:\n",(0,r.jsx)(n.a,{href:"/docs/next/all-issue-types#nil_insertion_into_collection",children:"Nil Insertion Into Collection"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"nullptr_dereference_in_nullsafe_class_latent",children:"NULLPTR_DEREFERENCE_IN_NULLSAFE_CLASS_LATENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#null-pointer-dereference",children:"Null pointer dereference"}),'. Reported as "Null Dereference" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A latent ",(0,r.jsx)(n.a,{href:"#nullptr_dereference_in_nullsafe_class",children:"NULLPTR_DEREFERENCE_IN_NULLSAFE_CLASS"}),". See the ",(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse#latent-issues",children:"documentation on Pulse latent issues"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"nullptr_dereference_latent",children:"NULLPTR_DEREFERENCE_LATENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#null-pointer-dereference",children:"Null pointer dereference"}),'. Reported as "Null Dereference" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A latent ",(0,r.jsx)(n.a,{href:"#nullptr_dereference",children:"NULLPTR_DEREFERENCE"}),". See the ",(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse#latent-issues",children:"documentation on Pulse latent issues"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"null_argument",children:"NULL_ARGUMENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "Null Argument" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objc",children:"This issue type indicates `nil` being passed as argument where a non-nil value expected.\n\n#import \n\n// Test (non-nil) returned values of NSString methods against `nil`\nNSString* stringNotNil(NSString* str) {\n if (!str) {\n // ERROR: NSString:stringWithString: expects a non-nil value\n\treturn [NSString stringWithString:nil];\n }\n return str;\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"null_argument_latent",children:"NULL_ARGUMENT_LATENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "Null Argument Latent" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A latent ",(0,r.jsx)(n.a,{href:"#null_argument",children:"NULL_ARGUMENT"}),". See the ",(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse#latent-issues",children:"documentation on Pulse latent issues"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"null_dereference",children:"NULL_DEREFERENCE"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#null-pointer-dereference",children:"Null pointer dereference"}),'. Reported as "Null Dereference" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-biabduction",children:"biabduction"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["See ",(0,r.jsx)(n.a,{href:"#nullptr_dereference",children:"NULLPTR_DEREFERENCE"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"optional_empty_access",children:"OPTIONAL_EMPTY_ACCESS"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "Optional Empty Access" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["Optional Empty Access warnings are reported when we try to retrieve the value of a ",(0,r.jsx)(n.a,{href:"https://github.com/facebook/folly/blob/master/folly/Optional.h",children:(0,r.jsx)(n.code,{children:"folly::Optional"})})," when it is empty (i.e. ",(0,r.jsx)(n.code,{children:"folly::none"}),")."]}),"\n",(0,r.jsxs)(n.p,{children:["In the following example we get a warning as ",(0,r.jsx)(n.code,{children:"int_opt"})," might be ",(0,r.jsx)(n.code,{children:"folly::none"})," and its value is being accessed:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-cpp",children:"bool somef(int v);\n\nfolly::Optional mightReturnNone(int v) {\n if (somef(v)) {\n return folly::Optional(v);\n }\n\n return folly::none;\n}\n\nint value_no_check() {\n folly::Optional int_opt = mightReturnNone (4);\n return int_opt.value(); // Optional Empty Access warning\n}\n"})}),"\n",(0,r.jsxs)(n.p,{children:["We do not get the warning anymore if we add a check whether ",(0,r.jsx)(n.code,{children:"int_opt"})," is not empty:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-cpp",children:"int value_check() {\n folly::Optional int_opt = mightReturnNone (4);\n if (int_opt.has_value()) {\n return int_opt.value(); // OK\n }\n return -1;\n}\n"})}),"\n",(0,r.jsx)(n.p,{children:"In some cases we know that we have a non-empty value and there is no need to have a check. Consider the following example where Infer does not warn:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-cpp",children:"bool somef(int v) {return v > 3;};\n\nfolly::Optional mightReturnNone(int v) {\n if (somef(v)) {\n return folly::Optional(v);\n }\n\n return folly::none;\n}\n\nint value_no_check() {\n folly::Optional int_opt = mightReturnNone (4); // cannot be folly::none\n return int_opt.value(); // OK\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"optional_empty_access_latent",children:"OPTIONAL_EMPTY_ACCESS_LATENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "Optional Empty Access Latent" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A latent ",(0,r.jsx)(n.a,{href:"#optional_empty_access",children:"OPTIONAL_EMPTY_ACCESS"}),". See the ",(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse#latent-issues",children:"documentation on Pulse latent issues"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"premature_nil_termination_argument",children:"PREMATURE_NIL_TERMINATION_ARGUMENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Premature Nil Termination Argument" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-biabduction",children:"biabduction"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This error type is reported in C and Objective-C. In many variadic methods,\n",(0,r.jsx)(n.code,{children:"nil"})," is used to signify the end of the list of input objects. This is similar\nto nil-termination of C strings. If one of the arguments that is not the last\nargument to the method is ",(0,r.jsx)(n.code,{children:"nil"})," as well, Infer reports an error because that may\nlead to unexpected behavior."]}),"\n",(0,r.jsxs)(n.p,{children:["An example of such variadic methods is\n",(0,r.jsx)(n.a,{href:"https://developer.apple.com/library/prerelease/ios/documentation/Cocoa/Reference/Foundation/Classes/NSArray_Class/index.html#//apple_ref/occ/clm/NSArray/arrayWithObjects",children:"arrayWithObjects"})]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objectivec",children:' NSArray *foo = [NSArray arrayWithObjects: @"aaa", str, @"bbb", nil];\n'})}),"\n",(0,r.jsxs)(n.p,{children:["In this example, if ",(0,r.jsx)(n.code,{children:"str"})," is ",(0,r.jsx)(n.code,{children:"nil"})," then an array ",(0,r.jsx)(n.code,{children:'@[@"aaa"]'})," of size 1 will be\ncreated, and not an array ",(0,r.jsx)(n.code,{children:'@[@"aaa", str, @"bbb"]'})," of size 3 as expected."]}),"\n",(0,r.jsx)(n.h2,{id:"pulse_cannot_instantiate_abstract_class",children:"PULSE_CANNOT_INSTANTIATE_ABSTRACT_CLASS"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "Cannot Instantiate Abstract Class" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["Instantiating an abstract class will lead to ",(0,r.jsx)(n.code,{children:"Cannot instantiate abstract class"})," error."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-hack",children:"abstract class AbstractClass1 {}\n\nclass ConcreteClass1 extends AbstractClass1 {}\n\npublic static function makeGeneric(classname $cls): void {\n new $cls();\n}\n\n<<__ConsistentConstruct>>\nabstract class AbstractClass2 {\n\n public static function makeStatic(): void {\n new static();\n }\n}\n\nclass ConcreteClass2 extends AbstractClass2 {}\n\npublic function badViaGeneric(): void {\n Main::makeGeneric(AbstractClass1::class); // ERROR!\n}\n\npublic function goodViaGeneric(): void {\n Main::makeGeneric(ConcreteClass1::class);\n}\n\npublic function badViaStatic(): void {\n AbstractClass2::makeStatic(); // ERROR!\n}\n\npublic function goodViaStatic(): void {\n ConcreteClass2::makeStatic();\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"pulse_const_refable",children:"PULSE_CONST_REFABLE"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#perf-regression",children:"Perf regression"}),'. Reported as "Const Refable Parameter" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This issue is reported when a function parameter is a) passed by value and b) is not modified inside the function. Instead, parameter can be passed by const reference, i.e. converted to a ",(0,r.jsx)(n.code,{children:"const&"})," so that no unnecessary copy is created at the callsite of the function."]}),"\n",(0,r.jsx)(n.p,{children:"For example,"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-cpp",children:"#include \n\nint read_first(const std::vector& vec) { return vec[0]; }\n\nvoid const_refable(std::vector vec) {\n int first = read_first(vec); // vec is never modified, so the parameter should have type const&\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"pulse_dict_missing_key",children:"PULSE_DICT_MISSING_KEY"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "Dict Missing Key" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This issue is similar to ",(0,r.jsx)(n.a,{href:"#pulse_uninitialized_value",children:(0,r.jsx)(n.code,{children:"PULSE_UNINITIALIZED_VALUE"})}),", but it is to warn\nreading a missing key of dictionary in Hack."]}),"\n",(0,r.jsxs)(n.p,{children:["For example, in the following code, the dictionary ",(0,r.jsx)(n.code,{children:"$d"})," has no entry for ",(0,r.jsx)(n.code,{children:"bye"}),", so reading\n",(0,r.jsx)(n.code,{children:"$d['bye']"})," will throw the ",(0,r.jsx)(n.code,{children:"OutOfBoundsException"})," exception, which is usually unexpected from\ndevelopers. We can use a safer function ",(0,r.jsx)(n.code,{children:"idx"})," instead when keys of a dictionary is unclear."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-hack",children:"function simple_bad() : int {\n $d = dict['hi' => 42, 'hello' => 52];\n return $d['bye'];\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"pulse_dynamic_type_mismatch",children:"PULSE_DYNAMIC_TYPE_MISMATCH"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "Dynamic Type Mismatch" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"This error is reported in Hack. It fires when we detect an operation that is incompatible\nwith the dynamic type of its arguments."}),"\n",(0,r.jsxs)(n.p,{children:["For example, reading ",(0,r.jsx)(n.code,{children:"$x['key']"})," when ",(0,r.jsx)(n.code,{children:"$x"})," is a vector."]}),"\n",(0,r.jsx)(n.h2,{id:"pulse_readonly_shared_ptr_param",children:"PULSE_READONLY_SHARED_PTR_PARAM"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#perf-regression",children:"Perf regression"}),'. Reported as "Read-only Shared Parameter" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This issue is reported when a shared pointer parameter is a) passed by value and b) is used only for reading, rather than lifetime extension. At the callsite, this might cause a potentially expensive unnecessary copy of the shared pointer, especially when many number of threads are sharing it. To avoid this, consider 1) passing the raw pointer instead and 2) use ",(0,r.jsx)(n.code,{children:"std::shared_ptr::get"})," at callsites."]}),"\n",(0,r.jsx)(n.p,{children:"For example,"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-cpp",children:"void callee(std::shared_ptr x) {\n // read_T(*x);\n}\n\nvoid caller() {\n callee(shared_ptr);\n}\n"})}),"\n",(0,r.jsx)(n.p,{children:"can be changed to"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-cpp",children:"void callee(T* p) {\n // read_T(*p);\n}\n\nvoid caller() {\n callee(shared_ptr.get());\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"pulse_reference_stability",children:"PULSE_REFERENCE_STABILITY"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#memory-error",children:"Memory error"}),'. Reported as "Reference Stability" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["The family of maps ",(0,r.jsx)(n.code,{children:"folly::F14ValueMap"}),", ",(0,r.jsx)(n.code,{children:"folly::F14VectorMap"}),", and by extension\n",(0,r.jsx)(n.code,{children:"folly::F14FastMap"})," differs slightly from ",(0,r.jsx)(n.code,{children:"std::unordered_map"})," as it does not\nprovide reference stability. When the map resizes such as when ",(0,r.jsx)(n.code,{children:"reserve"})," is\ncalled or new elements are added, all existing references become invalid and\nshould not be used."]}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"operator[]"})," is an interesting case as it can easily introduce unsafe code when\nused twice in the same expression. Depending on what keys are present and which\norder the compiler sequences sub-expressions, an insert via ",(0,r.jsx)(n.code,{children:"operator[]"})," can\ninvalidate a reference obtained in the same expression before it's read from.\nTypically, those cases can be improved by using other map functions such as\n",(0,r.jsx)(n.code,{children:"at"}),", ",(0,r.jsx)(n.code,{children:"find"}),", ",(0,r.jsx)(n.code,{children:"emplace"}),", or ",(0,r.jsx)(n.code,{children:"insert_or_assign"})," to increase code quality and\nsafety."]}),"\n",(0,r.jsx)(n.p,{children:"Examples:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-cpp",children:"#include \n\nvoid use_reference_after_growth_bad(folly::F14FastMap& map) {\n const auto& valueRef = map.at(1);\n map.emplace(13, 71);\n const auto valueCopy = valueRef;\n}\n\nvoid unsafe_expressions_bad(folly::F14FastMap& map) {\n // Unsafe expressions in situations where one or both keys are not present.\n map[13] = map[71];\n const auto p = map[13] * map[71];\n const auto q = f(map[13], map[71]);\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"pulse_resource_leak",children:"PULSE_RESOURCE_LEAK"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#resource-leak",children:"Resource leak"}),'. Reported as "Resource Leak" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["See ",(0,r.jsx)(n.a,{href:"#resource_leak",children:"RESOURCE_LEAK"})]}),"\n",(0,r.jsx)(n.h2,{id:"pulse_transitive_access",children:"PULSE_TRANSITIVE_ACCESS"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#logic-error",children:"Logic error"}),'. Reported as "Transitive Access" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"This issue tracks spurious accesses that are reachable from specific entry functions."}),"\n",(0,r.jsx)(n.p,{children:"Spurious accesses are specified as specific load/calls."}),"\n",(0,r.jsx)(n.p,{children:"Entry functions are specified through their enclosing class that must extend a specific\nclass and should not extend a list of specific classes."}),"\n",(0,r.jsx)(n.h2,{id:"pulse_unawaited_awaitable",children:"PULSE_UNAWAITED_AWAITABLE"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#resource-leak",children:"Resource leak"}),'. Reported as "Unawaited Awaitable" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"Awaitable"})," values created by calls to asynchronous methods should eventually be ",(0,r.jsx)(n.code,{children:"await"}),"ed along all codepaths (even if their value is unused). Hence the following is ",(0,r.jsx)(n.em,{children:"not"})," OK"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-hack",children:"class A {\n public static async genInt() : Awaitable{\n // typically do something involving IO\n }\n\n public static async genBad() : Awaitable {\n $_unused = self::genInt(); // ERROR: should have done $_unused = await self::genInt();\n return;\n }\n}\n"})}),"\n",(0,r.jsxs)(n.p,{children:["Failure to ",(0,r.jsx)(n.code,{children:"await"})," an ",(0,r.jsx)(n.code,{children:"Awaitable"})," can lead to non-deterministic amount of the asynchronous call actually being executed, and can also indicate a logical confusion between ",(0,r.jsx)(n.code,{children:"T"})," and ",(0,r.jsx)(n.code,{children:"Awaitable"})," that may not be caught by the type-checker."]}),"\n",(0,r.jsx)(n.h2,{id:"pulse_unfinished_builder",children:"PULSE_UNFINISHED_BUILDER"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#resource-leak",children:"Resource leak"}),'. Reported as "Unfinished Builder" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"Classes adhering to builder pattern are usually expected to call a finalizer function at some point to produce final result based on values that were passed to a builder itself. If finalizer function hasn't been called then builder's data won't be consumed in any meaningful way and will just be discarded."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-hack",children:"class MyBuilder {\n private int $a = 0;\n private int $b = 0;\n\n public function setA(int $a): MyBuilder {\n $this->a = $a;\n return $this;\n }\n\n public function setB(int $b): MyBuilder {\n $this->b = $b;\n return $this;\n }\n\n public function saveX(): Awaitable {\n // typically do something involving IO\n }\n}\n\nclass BuilderTester {\n public static function builderUserOK(): void {\n $b = new MyBuilder(0);\n $b->setA(42)->setB(97)->saveX();\n }\n\n public static function builderUserBad(): void {\n $b = new MyBuilder(0);\n $b->setA(42)->setB(97); // ERROR: saveX hasn't been called so the builder's data is discarded\n }\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"pulse_uninitialized_const",children:"PULSE_UNINITIALIZED_CONST"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "Uninitialized Const" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This issue is similar to ",(0,r.jsx)(n.a,{href:"#pulse_uninitialized_value",children:(0,r.jsx)(n.code,{children:"PULSE_UNINITIALIZED_VALUE"})}),", but it is to detect the uninitialized abstract const value in Hack."]}),"\n",(0,r.jsxs)(n.p,{children:["For example, in the following code, the ",(0,r.jsx)(n.code,{children:"FIELD"})," can be read by the static method ",(0,r.jsx)(n.code,{children:"get_field"}),"."]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["It is problematic invoking ",(0,r.jsx)(n.code,{children:"static::FIELD"}),", since it may be resolved to a ",(0,r.jsx)(n.code,{children:"A::FIELD"})," access, if called from ",(0,r.jsx)(n.code,{children:"A::get_field()"}),". Because ",(0,r.jsx)(n.code,{children:"FIELD"})," is abstract in ",(0,r.jsx)(n.code,{children:"A"}),", it is never assigned a value and the vm will crash. Unfortunately, Hack's type system cannot catch this."]}),"\n",(0,r.jsxs)(n.li,{children:["In the ",(0,r.jsx)(n.code,{children:"B"})," class, ",(0,r.jsx)(n.code,{children:"FIELD"})," is initialized, thus invoking ",(0,r.jsx)(n.code,{children:"B::get_field"})," is safe."]}),"\n"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-hack",children:'abstract class A {\n abstract const string FIELD;\n \n public static function get_field(): string {\n return static::FIELD;\n }\n}\n\nfunction call_get_field_bad(): string {\n return A::get_field();\n}\n\nclass B extends A {\n const string FIELD = "defined";\n}\n\nfunction call_get_field_ok(): string {\n return B::get_field();\n}\n'})}),"\n",(0,r.jsx)(n.h2,{id:"pulse_uninitialized_method",children:"PULSE_UNINITIALIZED_METHOD"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#runtime-exception",children:"Runtime exception"}),'. Reported as "Uninitialized Method" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This issue is similar to ",(0,r.jsx)(n.a,{href:"#pulse_uninitialized_const",children:(0,r.jsx)(n.code,{children:"PULSE_UNINITIALIZED_CONST"})}),", but it is to detect the uninitialized method call in Hack."]}),"\n",(0,r.jsxs)(n.p,{children:["For example, in the following code, the static method ",(0,r.jsx)(n.code,{children:"foo"})," is declared only in the interface and the abstract class. Thus, calling the static method can introduce an unexpected exception or a fatal error, while the type checker does miss the issue."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-hack",children:"interface MyInterface {\n public static function foo(): string;\n}\n\nabstract class MyAbstractClass {\n public abstract static function foo(): string;\n}\n\nfunction interface_method_static_method_bad(): string {\n // Uncaught exception 'TypehintViolationException'\n $c = MyInterface::class;\n return $c::foo();\n}\n\nfunction abstract_class_static_method_bad(): string {\n // Fatal error: Cannot call abstract method\n $c = MyAbstractClass::class;\n return $c::foo();\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"pulse_uninitialized_value",children:"PULSE_UNINITIALIZED_VALUE"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#memory-error",children:"Memory error"}),'. Reported as "Uninitialized Value" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"The code uses a variable that has not been initialized, leading to unpredictable or unintended results."}),"\n",(0,r.jsx)(n.p,{children:"Using uninitialized values can lead to undefined behaviors possibly resulting in crashes, security failures and invalid results."}),"\n",(0,r.jsx)(n.p,{children:"This can easily be fixed by assigning all variables to an initial value when declaring them."}),"\n",(0,r.jsx)(n.p,{children:"This, for example, in C:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-c",children:"struct coordinates {\n int x;\n int y;\n};\n\nvoid foo() {\n struct coordinates c;\n c.x = 42;\n c.y++; // uninitialized value c.y!\n\n int z;\n if (z == 0) { // uninitialized value z!\n // something\n }\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"pulse_unnecessary_copy",children:"PULSE_UNNECESSARY_COPY"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#perf-regression",children:"Perf regression"}),'. Reported as "Unnecessary Copy" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"This is reported when Infer detects an unnecessary copy of an object via copy constructor where neither the source nor the copied variable are modified before the variable goes out of scope. Rather than the copy, a reference to the source object could be used to save memory."}),"\n",(0,r.jsx)(n.p,{children:"For example,"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-cpp",children:"struct A {\n int a;\n};\n\nint unnecessary_copy(A& x){\n auto y = x; // calls copy constructor\n return y.a; // y is not modified after copy, hence we could avoid the copy by adding & after auto as below\n}\n\nint use_reference_instead(A& x){\n auto& y = x; // copy the ref only\n return y.a;\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"pulse_unnecessary_copy_assignment",children:"PULSE_UNNECESSARY_COPY_ASSIGNMENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#perf-regression",children:"Perf regression"}),'. Reported as "Unnecessary Copy Assignment" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["See ",(0,r.jsx)(n.a,{href:"#pulse_unnecessary_copy",children:"PULSE_UNNECESSARY_COPY"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"pulse_unnecessary_copy_assignment_const",children:"PULSE_UNNECESSARY_COPY_ASSIGNMENT_CONST"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#perf-regression",children:"Perf regression"}),'. Reported as "Unnecessary Copy Assignment from Const" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["See ",(0,r.jsx)(n.a,{href:"#pulse_unnecessary_copy",children:"PULSE_UNNECESSARY_COPY"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"pulse_unnecessary_copy_assignment_movable",children:"PULSE_UNNECESSARY_COPY_ASSIGNMENT_MOVABLE"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#perf-regression",children:"Perf regression"}),'. Reported as "Unnecessary Copy Assignment Movable" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["See ",(0,r.jsx)(n.a,{href:"#pulse_unnecessary_copy_movable",children:"PULSE_UNNECESSARY_COPY_MOVABLE"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"pulse_unnecessary_copy_intermediate",children:"PULSE_UNNECESSARY_COPY_INTERMEDIATE"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#perf-regression",children:"Perf regression"}),'. Reported as "Unnecessary Copy Intermediate" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This is reported when Infer detects an unnecessary temporary copy of an intermediate object where copy is created to be passed down to a function unnecessarily. Instead, the intermediate object should either be moved into the callee or the type of the callee's parameter should be made ",(0,r.jsx)(n.code,{children:"const &"}),"."]}),"\n",(0,r.jsx)(n.p,{children:"A prime example of this occurs when we call a function with a call-by-value parameter as follows:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-cpp",children:"void callee(ExpensiveObject obj) {\n // ....\n}\n\nvoid caller() {\n callee(myExpensiveObj); // a copy of myExpensiveObj is created\n // the copy is destroyed right after the call \n}\n"})}),"\n",(0,r.jsxs)(n.p,{children:["In this case, when we call ",(0,r.jsx)(n.code,{children:"callee"}),", under the hood, a copy of the argument ",(0,r.jsx)(n.code,{children:"myExpensiveObj"})," is created to be passed to the function call. However, the copy might be unnecessary if"]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"callee"})," doesn\u2019t modify its parameter \u2192 then we can change its type to ",(0,r.jsx)(n.code,{children:"const ExpensiveObject&"}),", getting rid of the copy at caller"]}),"\n",(0,r.jsxs)(n.li,{children:["even if ",(0,r.jsx)(n.code,{children:"callee"})," might modify the object, if the argument ",(0,r.jsx)(n.code,{children:"myExpensiveObj"})," is never used later on, we can get rid of the copy by moving it instead: ",(0,r.jsx)(n.code,{children:"callee(std::move(myExpensiveObj))"}),"."]}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:["The analysis is careful about suggesting moves blindly though: if the argument ",(0,r.jsx)(n.code,{children:"myExpensiveObj"})," is of type ",(0,r.jsx)(n.code,{children:"const & ExpensiveObject"})," then we also recommend that for move to work, const-reference needs to be removed."]}),"\n",(0,r.jsx)(n.p,{children:"PS: We check for other conditions on the argument here: e.g. it should be local to the procedure, as moving a non-local member might cause other memory correctness issues like use-after-move later on."}),"\n",(0,r.jsx)(n.h2,{id:"pulse_unnecessary_copy_intermediate_const",children:"PULSE_UNNECESSARY_COPY_INTERMEDIATE_CONST"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#perf-regression",children:"Perf regression"}),'. Reported as "Unnecessary Copy Intermediate from Const" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["See ",(0,r.jsx)(n.a,{href:"#pulse_unnecessary_copy",children:"PULSE_UNNECESSARY_COPY"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"pulse_unnecessary_copy_movable",children:"PULSE_UNNECESSARY_COPY_MOVABLE"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#perf-regression",children:"Perf regression"}),'. Reported as "Unnecessary Copy Movable" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"This is reported when Infer detects an unnecessary copy into a field where"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"the source is an rvalue-reference"}),"\n",(0,r.jsx)(n.li,{children:"the source is not modified before it goes out of scope or is destroyed."}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"Note that the copy can be modified since it has the ownership of the object."}),"\n",(0,r.jsx)(n.p,{children:"Fix: Rather than the copying into the field, the source should be moved into it."}),"\n",(0,r.jsx)(n.p,{children:"For example,"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-cpp",children:"struct A {\n std::vector vec;\n};\n\nclass Test {\n A mem_a;\n\n void unnecessary_copy(A&& src) {\n mem_a = src;\n // fix is to move as follows\n // mem_a = std::move(src);\n }\n\n};\n\n"})}),"\n",(0,r.jsx)(n.h2,{id:"pulse_unnecessary_copy_optional",children:"PULSE_UNNECESSARY_COPY_OPTIONAL"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#perf-regression",children:"Perf regression"}),'. Reported as "Unnecessary Copy to Optional" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This is reported when Infer detects an unnecessary copy of an object via ",(0,r.jsx)(n.code,{children:"optional"})," value\nconstruction where the source is not modified before it goes out of scope. To avoid the copy, we\ncan move the source object or change the callee's type."]}),"\n",(0,r.jsx)(n.p,{children:"For example,"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-cpp",children:"void get_optional_value(std::optional x) {}\n\nvoid pass_non_optional_value(A x) {\n get_optional_value(x);\n // fix is to move as follows\n // get_optional_value(std::move(x));\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"pulse_unnecessary_copy_optional_const",children:"PULSE_UNNECESSARY_COPY_OPTIONAL_CONST"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#perf-regression",children:"Perf regression"}),'. Reported as "Unnecessary Copy to Optional from Const" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["See ",(0,r.jsx)(n.a,{href:"#pulse_unnecessary_copy_optional",children:"PULSE_UNNECESSARY_COPY_OPTIONAL"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"pulse_unnecessary_copy_return",children:"PULSE_UNNECESSARY_COPY_RETURN"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#perf-regression",children:"Perf regression"}),'. Reported as "Unnecessary Copy Return" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This is similar to ",(0,r.jsx)(n.a,{href:"#pulse_unnecessary_copy",children:"PULSE_UNNECESSARY_COPY"}),", but reported when a callee returns a copied value and it is not modified in its caller. We may be able to return const-ref typed value or try ",(0,r.jsx)(n.code,{children:"std::move"})," to avoid the copy."]}),"\n",(0,r.jsx)(n.p,{children:"For example,"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-cpp",children:"class MyClass {\n T v;\n public:\n T get() {\n return v; // v is copied here, which is avoidable.\n }\n};\n\nvoid caller(MyClass obj) {\n T x = obj.get();\n std::cout << x; // x is not modified.\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"pulse_unnecessary_copy_thrift_assignment",children:"PULSE_UNNECESSARY_COPY_THRIFT_ASSIGNMENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#perf-regression",children:"Perf regression"}),'. Reported as "Unnecessary Copy Assignment into Thrift" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This is similar to ",(0,r.jsx)(n.a,{href:"#pulse_unnecessary_copy_assignment",children:"PULSE_UNNECESSARY_COPY_ASSIGNMENT"}),", but is\nreported when copied into thrift fields."]}),"\n",(0,r.jsx)(n.h2,{id:"pure_function",children:"PURE_FUNCTION"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Pure Function" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-purity",children:"purity"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"This issue type indicates pure functions. For instance, below functions would be marked as pure:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"int local_write_pure(int x, int y) {\n int k = x + y;\n k++;\n return k;\n}\n\n// no change to outside state, the local allocation is ok.\nint local_alloc_pure(ArrayList list) {\n ArrayList list_new = new ArrayList();\n for (Integer el : list) {\n list_new.add(el);\n }\n return list_new.size();\n}\n"})}),"\n",(0,r.jsx)(n.p,{children:"However, the following ones would not be pure:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"void swap_impure(int[] array, int i, int j) {\n int tmp = array[i];\n array[i] = array[j]; // modifying the input array\n array[j] = tmp;\n}\n\nint a = 0;\nvoid set_impure(int x, int y) {\n a = x + y; //modifying a global variable\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"regex_op_on_ui_thread",children:"REGEX_OP_ON_UI_THREAD"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#perf-regression",children:"Perf regression"}),'. Reported as "Regex Op On Ui Thread" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-starvation",children:"starvation"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"A potentially costly operation on a regular expression occurs on the UI thread."}),"\n",(0,r.jsx)(n.h2,{id:"resource_leak",children:"RESOURCE_LEAK"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#resource-leak",children:"Resource leak"}),'. Reported as "Resource Leak" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-biabduction",children:"biabduction"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"Infer reports resource leaks in C, Objective-C and Java. In general, resources\nare entities such as files, sockets, connections, etc, that need to be closed\nafter being used."}),"\n",(0,r.jsx)(n.h3,{id:"resource-leak-in-c",children:"Resource leak in C"}),"\n",(0,r.jsx)(n.p,{children:"This is an example of a resource leak in C code:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-c",children:'-(void) resource_leak_bug {\n FILE *fp;\n fp=fopen("c:\\\\test.txt", "r"); // file opened and not closed.\n}\n'})}),"\n",(0,r.jsx)(n.h3,{id:"resource-leak-in-java",children:"Resource leak in Java"}),"\n",(0,r.jsx)(n.p,{children:"For the remaining of this section, we will consider examples of resource leaks\nin Java code."}),"\n",(0,r.jsxs)(n.p,{children:["TIP: A common source of bugs is ",(0,r.jsx)("b",{children:"exceptions skipping past close()\nstatements"}),". That is the first thing to look for if INFER reports a potential\nresource leak."]}),"\n",(0,r.jsx)(n.h3,{id:"basics-and-standard-idiom",children:"Basics and Standard Idiom"}),"\n",(0,r.jsxs)(n.p,{children:["Some objects in Java, the ",(0,r.jsx)("i",{children:"resources"}),", are supposed to be closed when you\nstop using them, and failure to close is a ",(0,r.jsx)("i",{children:"resource leak"}),". Resources\ninclude input streams, output streams, readers, writers, sockets, http\nconnections, cursors, and json parsers."]}),"\n",(0,r.jsx)(n.p,{children:"The standard idiom is"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:" // Standard idiom\n Allocate resource\n try {\n do some stuff\n } finally {\n close resource\n }\n"})}),"\n",(0,r.jsx)(n.p,{children:"or more for example,"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:' // Standard Idiom\n public static void foo () throws IOException{\n FileOutputStream fos = new FileOutputStream(new File("whatever.txt"));\n try {\n fos.write(7);\n } finally {\n fos.close();\n }\n }\n'})}),"\n",(0,r.jsx)(n.p,{children:"and you should use the standard idiom for the most part, when you don't want to\nreturn the resource to the surrounding context."}),"\n",(0,r.jsx)(n.p,{children:"Sometimes people just leave out close(), and that is a bug, but more typically\nexceptional paths are the root of the problem, as in"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:' // leak because of exception\n public static void foo () throws IOException {\n FileOutputStream fos = new FileOutputStream(new File("whatever.txt"));\n fos.write(7); //DOH! What if exception?\n fos.close();\n }\n'})}),"\n",(0,r.jsx)(n.p,{children:"where an exception in fos.write will cause execution to skip past the close()\nstatement."}),"\n",(0,r.jsx)(n.h4,{id:"multiple-resources-bugs",children:"Multiple Resources Bugs"}),"\n",(0,r.jsx)(n.p,{children:"We can deal with multiple resources correctly and simply just by nesting the\nstandard idiom."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:' // Two Resources nested\n public static void foo() throws IOException {\n FileInputStream fis = new FileInputStream(new File("whatever.txt"));\n try {\n FileOutputStream fos = new FileOutputStream(new File("everwhat.txt"));\n try {\n fos.write(fis.read());\n } finally {\n fos.close();\n }\n } finally {\n fis.close();\n }\n }\n'})}),"\n",(0,r.jsx)(n.p,{children:"Bugs often occur when using multiple resources in other ways because of\nexceptions in close() methods. For example,"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:' // Classic Two Resources Bug\n public static void foo() throws IOException {\n FileInputStream fis = null;\n FileOutputStream fos = null;\n try {\n fis = new FileInputStream(new File("whatever.txt"));\n fos = new FileOutputStream(new File("everwhat.txt"));\n fos.write(fis.read());\n } finally {\n if (fis!=null) fis.close();\n if (fos!=null) fos.close();\n }\n }\n'})}),"\n",(0,r.jsx)(n.p,{children:"Here, if there is an exception in the call to fis.close() execution will skip\npast fos.close(); a leak."}),"\n",(0,r.jsx)(n.p,{children:"Another way, besides the standard idiom, to deal with this problem is to swallow\nexceptions."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:' // Two Resources Fix 1\n public static void foo() throws IOException {\n FileInputStream fis = null;\n FileOutputStream fos = null;\n try {\n fis = new FileInputStream(new File("whatever.txt"));\n fos = new FileOutputStream(new File("everwhat.txt"));\n fos.write(fis.read());\n } finally {\n try {\n if (fis!=null) fis.close();\n } catch (Exception e) {}; // Exception swallowing\n if (fos!=null) fos.close();\n }\n }\n'})}),"\n",(0,r.jsxs)(n.p,{children:["You can also swallow the exception on the output stream. Some people prefer not\nto swallow output stream exceptions, and also flush before closing.\n",(0,r.jsx)(n.a,{href:"http://code.google.com/p/guava-libraries/issues/detail?id=1118",children:"http://code.google.com/p/guava-libraries/issues/detail?id=1118"})]}),"\n",(0,r.jsx)(n.p,{children:"Notice that the nested standard idiom does not need the checks for null, which\nare in there in this case to protect against the case when one of the\nallocations throws an exception, in which case one would get a\nNullPointerException."}),"\n",(0,r.jsx)(n.h3,{id:"nested_allocations",children:"Nested_Allocations"}),"\n",(0,r.jsx)(n.p,{children:"When a resource allocation is included as an argument to a constructor, if the\nconstructor fails it can leave an unreachable resource that no one can close."}),"\n",(0,r.jsx)(n.p,{children:"For example gzipOutputStream = new GZIPOutputStream(new FileOutputStream(out));\nis bad in case the outer constructor, GZIPOutputStream, throws an exception. In\nthat case, no one will have a hold of the FileOutputStream and so no one will be\nable to close it."}),"\n",(0,r.jsx)(n.p,{children:"In such a case you need to move the allocation the FileOutputStream out of the\nnested position and name it, so you are able to close if anything goes wrong\nduring execution of the GZIPOutputStream constructor."}),"\n",(0,r.jsx)(n.p,{children:"Here are resources that can throw exceptions i their constructor(s)."}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"ObjectInputStream , ObjectOutputStream, PipedInputStream, PipedOutputStream,\nPipedReader, PipedWriter, JarInputStream, JarOutputStream, GZIPInputStream,\nGZIPOutputStream , ZipFile all throw IOException"}),"\n",(0,r.jsx)(n.li,{children:"PrintStream throws UnsupportedEncodingException"}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"The constructors for FileInputStream, FileOutputStream and RandomAccessFile\nthrow FileNotFoundException, but these cases are not problematic in the sense\nthat their arguments are not resources and so they do not cause the nested\nresource leak."}),"\n",(0,r.jsx)(n.h3,{id:"allocation-of-jsonparser-and-cursor-resources",children:"Allocation of JSonParser and Cursor resources"}),"\n",(0,r.jsx)(n.p,{children:'Some resources are created inside libraries instead of by "new".'}),"\n",(0,r.jsx)(n.p,{children:"Cursor is an interface, the actual resources are something like SQLiteCursor.\nSo, every time you call a function that returns a Cursor object, there is an\nallocation."}),"\n",(0,r.jsx)(n.p,{children:"For instance, in the functions from SQLiteDatabase query(\u2026) and rawQuery(\u2026)\nallocate a cursor resource. For SQLiteQueryBuilder, ContentProviderClient,\nContentResolver. MediaStore and DownloadManager it is only query(\u2026) Cursor\nobjects cursor created by these functions need to be closed (i.e.,\ncursor.close())."}),"\n",(0,r.jsx)(n.p,{children:"Similarly, JsonParser is an abstract class, and create a resource in functions\nfrom the class JsonFactory createParser(byte[] data) createParser(byte[] data,\nint offset, int len) createParser(String content) createParser(URL url)\ncreateParser(File f) JsonParser objects js created by these functions need to be\nclosed (jp.close()). On the other hand . JasonParsers gotten from\ncreateParser(InputStream in) and createParser(Reader r) give you JsonParsers\nthat don\u2019t need to be closed. This is because they receive the resource from\nsomewhere that will maintain the responsibility to close it."}),"\n",(0,r.jsx)(n.h3,{id:"escaping-resources-and-exceptions",children:"Escaping resources and exceptions"}),"\n",(0,r.jsx)(n.p,{children:"Sometimes you want to return a resource to the outside, in which case you should\nnot close it, but you still need to be careful of exceptions in case control\nskips past the return leaving no one to close. Here is a simple example of a\npositive use of escaping resources."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:" // An escaping resource, shouldn't close\n public BugReportAttachment createAttachment(File reportDirectory, String fileName)\n throws FileNotFoundException {\n File file = new File(reportDirectory, fileName);\n OutputStream stream = new FileOutputStream(file);\n return new BugReportAttachment(Uri.fromFile(file), stream);\n }\n"})}),"\n",(0,r.jsxs)(n.p,{children:["In this case it is intended that an object that wraps ",(0,r.jsx)(n.code,{children:"stream"})," is passed to the\ncaller of ",(0,r.jsx)(n.code,{children:"createAttachment"}),". You should certainly not close stream here,\nbecause it is being passed to the outside."]}),"\n",(0,r.jsx)(n.p,{children:"But for escaping resources like this you still need to be careful of exceptions.\nFor example, in"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:" // An escaping resource, and a leak\n public BugReportAttachment createAttachment(File reportDirectory, String fileName)\n throws FileNotFoundException {\n File file = new File(reportDirectory, fileName);\n OutputStream stream = new FileOutputStream(file);\n stream.write(7);\n return new BugReportAttachment(Uri.fromFile(file), stream);\n }\n"})}),"\n",(0,r.jsx)(n.p,{children:"if stream.write(7) throws an exception, then no one will have a hold of stream,\nand no one will be able to close it; a leak."}),"\n",(0,r.jsx)(n.h3,{id:"java-7s-try-with-resources",children:"Java 7's try-with-resources"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"(For use with Java 7 only)"})}),"\n",(0,r.jsx)(n.p,{children:"Clearly, accounting for the ramifications of all the exceptional cases is\ncomplicated, and there is a better way in Java 7."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:' // Two Resources Fix 2; via try-with-resources\n public static void foo() throws IOException {\n try (\n FileInputStream fis = new FileInputStream(new File("whatever.txt"));\n FileOutputStream fos = new FileOutputStream(new File("everwhat.txt"))\n ) {\n fos.write(fis.read());\n }\n }\n'})}),"\n",(0,r.jsx)(n.p,{children:"All the complicated exceptional cases above are (apparently) covered by this\nconstruct, and the result is much simpler."}),"\n",(0,r.jsx)(n.p,{children:"So, if you are trying to fix a potential leak in code with multiples resources\nyou can go ahead and try to understand whether the potential leak is real. Or,\nif the code is complex and it is hard to figure out, it would be perfectly\nlegitimate to simply convert the code over to try-with-resources if you have\naccess to Java 7, so as to save yourself some brain-cycles. You will also end up\nwith cleaner code."}),"\n",(0,r.jsxs)(n.p,{children:["If try-with-resources is so great you should ",(0,r.jsx)("i",{children:"always"}),' use it. But you\nshouldn\'t\u2026 Try-with-resources gives resources static scoping, and works via a\nstack discipline. Sometimes, you want a resource to persist beyond scope, as in\nthe escaping example above. In an escaping example maybe you could refactor lots\nof code so that try-with-resources applies, and maybe you cannot in a sensible\nway. This just illustrates that, though you might hear people say that\ntry-with-resources "solves" the resource problem, it does not. It is very\nuseful, but you cannot use it blindly when you see a resource-allocation site.']}),"\n",(0,r.jsx)(n.h2,{id:"retain_cycle",children:"RETAIN_CYCLE"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#resource-leak",children:"Resource leak"}),'. Reported as "Retain Cycle" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"A retain cycle is a situation when object A retains object B, and object B\nretains object A at the same time. Here is an example:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objectivec",children:"@class Child;\n@interface Parent : NSObject {\n Child *child; // Instance variables are implicitly __strong\n}\n@end\n@interface Child : NSObject {\n Parent *parent;\n}\n@end\n"})}),"\n",(0,r.jsx)(n.p,{children:'You can fix a retain cycle in ARC by using __weak variables or weak properties\nfor your "back links", i.e. links to direct or indirect parents in an object\nhierarchy:'}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objectivec",children:"@class Child;\n@interface Parent : NSObject {\n Child *child;\n}\n@end\n@interface Child : NSObject {\n __weak Parent *parent;\n}\n@end\n"})}),"\n",(0,r.jsx)(n.h2,{id:"retain_cycle_no_weak_info",children:"RETAIN_CYCLE_NO_WEAK_INFO"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#resource-leak",children:"Resource leak"}),'. Reported as "Retain Cycle No Weak Info" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"A retain cycle is a situation when object A retains object B, and object B\nretains object A at the same time. Here is an example:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objectivec",children:"@class Child;\n@interface Parent : NSObject {\n Child *child; // Instance variables are implicitly __strong\n}\n@end\n@interface Child : NSObject {\n Parent *parent;\n}\n@end\n"})}),"\n",(0,r.jsx)(n.p,{children:'You can fix a retain cycle in ARC by using __weak variables or weak properties\nfor your "back links", i.e. links to direct or indirect parents in an object\nhierarchy:'}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objectivec",children:"@class Child;\n@interface Parent : NSObject {\n Child *child;\n}\n@end\n@interface Child : NSObject {\n __weak Parent *parent;\n}\n@end\n"})}),"\n",(0,r.jsx)(n.h2,{id:"scope_leakage",children:"SCOPE_LEAKAGE"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#sensitive-data-flow",children:"Sensitive data flow"}),'. Reported as "Scope Leakage" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-scope-leakage",children:"scope-leakage"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:'This issue type indicates that a class with scope annotation A stores a field\nwith whose (dynamic) type (or one of its super types) is annotated with scope\nB such that a scope nesting restriction is violated. By "stores", we mean\neither directly or transitively.'}),"\n",(0,r.jsx)(n.p,{children:"A configuration is used to list the set of scopes and the must-not-hold relation."}),"\n",(0,r.jsx)(n.p,{children:"In the following Java example, the set of scopes is Outer and Inner, and the must-not-hold\nrelation is simply {(Outer, Inner)}:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"@ScopeType(value = Outer.class)\nclass ClassOfOuterScope {\n final ClassOfInner c = new ClassOfInner(); // <-- warn here that ClassOfInner would leak.\n}\n\n@ScopeType(value = Inner.class)\nclass ClassOfInner {}\n"})}),"\n",(0,r.jsx)(n.p,{children:"Here is a more detailed description of the analysis."}),"\n",(0,r.jsx)(n.p,{children:'This analysis operates over Java bytecode. It assumes that types (classes, interfaces, enums,\netc.) may be annotated with so-called scope annotations. The analysis is parameterized by a set\nof scopes and a "must-not-hold" relation over pairs of scopes, which it reads from a\nconfiguration file.'}),"\n",(0,r.jsx)(n.p,{children:'The analysis aims to detect violations of the following property: if there exist a path of\nfields from object OA to object OB and the type of OA (or one of its super-types) is annotated\nwith scope SA and the type of OB (or one of its super-types) is annotated with scope SB then\nmust-not-hold(SA, SB) must be false. Intuitively, the given objects have different scopes that\nshould not be nested, for example, different intended lifetimes, and a forbidden path from OA to\nOB results in OB "leaking" out of the scope SA.'}),"\n",(0,r.jsx)(n.p,{children:'The implementation reads a configuration to determine a list of (scope) "generators" for each\ntype of scope and a scope class for each type of scope. A generator for a scope type SA is given\nby the name of a class and a list of methods where it is understood that any of the methods\nlisted for the given class returns an object that is known to have scope SA. (This can be seen\nas a form of lightweight modeling.) A scope class is the name of the class that represents a\ngiven scope.'}),"\n",(0,r.jsx)(n.h2,{id:"self_in_block_passed_to_init",children:"SELF_IN_BLOCK_PASSED_TO_INIT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#resource-leak",children:"Resource leak"}),'. Reported as "Self In Block Passed To Init" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-self-in-block",children:"self-in-block"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This check flags when ",(0,r.jsx)(n.code,{children:"self"})," is captured in a block that is passed to an initialiser method. That\ncould cause retain cycles if the initialiser code retains the block."]}),"\n",(0,r.jsx)(n.p,{children:"Example:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objectivec",children:" [obj initWithHandler:^() {\n [self foo];\n ...\n }];\n"})}),"\n",(0,r.jsxs)(n.p,{children:["Instead it's better to use the ",(0,r.jsx)(n.code,{children:"weakSelf"}),"/",(0,r.jsx)(n.code,{children:"strongSelf"})," pattern."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objectivec",children:" __weak __typeof(self) weakSelf = self;\n [obj initWithHandler:^() {\n __strong __typeof(weakSelf) strongSelf = weakSelf;\n if (strongSelf) {\n [strongSelf foo];\n }\n ...\n }];\n"})}),"\n",(0,r.jsx)(n.h2,{id:"sensitive_data_flow",children:"SENSITIVE_DATA_FLOW"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#sensitive-data-flow",children:"Sensitive data flow"}),'. Reported as "Sensitive Data Flow" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"A flow of sensitive data was detected from a source."}),"\n",(0,r.jsx)(n.h2,{id:"stack_variable_address_escape",children:"STACK_VARIABLE_ADDRESS_ESCAPE"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#memory-error",children:"Memory error"}),'. Reported as "Stack Variable Address Escape" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"Reported when an address pointing into the stack of the current\nfunction will escape to its calling context. Such addresses will\nbecome invalid by the time the function actually returns so are\npotentially dangerous."}),"\n",(0,r.jsx)(n.p,{children:"For example, directly returning a pointer to a local variable:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-C",children:'int* foo() {\n int x = 42;\n return &x; // <-- warn here that "&x" will escape\n}\n'})}),"\n",(0,r.jsx)(n.h2,{id:"starvation",children:"STARVATION"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "UI Thread Starvation" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-starvation",children:"starvation"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"This error is reported in Java, and specifically on Android. These reports are\ntriggered when a method that runs on the UI thread may block, thus potentially\nleading to an Application Not Responding error."}),"\n",(0,r.jsx)(n.p,{children:"Infer considers a method as running on the UI thread whenever:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["The method, one of its overrides, its class, or an ancestral class, is\nannotated with ",(0,r.jsx)(n.code,{children:"@UiThread"}),"."]}),"\n",(0,r.jsxs)(n.li,{children:["The method, or one of its overrides is annotated with ",(0,r.jsx)(n.code,{children:"@OnEvent"}),", ",(0,r.jsx)(n.code,{children:"@OnClick"}),",\netc."]}),"\n",(0,r.jsxs)(n.li,{children:["The method or its callees call a ",(0,r.jsx)(n.code,{children:"Litho.ThreadUtils"})," method such as\n",(0,r.jsx)(n.code,{children:"assertMainThread"}),"."]}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"The issue is reported when a method deemed to run on the UI thread"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Makes a method call which may block."}),"\n",(0,r.jsx)(n.li,{children:"Takes a lock, and another thread takes the same lock, and before releasing it,\nmakes a call that may block."}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"Calls that may block are considered:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Certain I/O calls."}),"\n",(0,r.jsxs)(n.li,{children:["Two way ",(0,r.jsx)(n.code,{children:"Binder.transact"})," calls."]}),"\n",(0,r.jsx)(n.li,{children:"Certain OS calls."}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"Future"})," or ",(0,r.jsx)(n.code,{children:"AsyncTask"})," calls to ",(0,r.jsx)(n.code,{children:"get"})," without timeouts, or with too large\ntimeouts."]}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:["To suppress starvation reports in a method ",(0,r.jsx)(n.code,{children:"m()"})," use the\n",(0,r.jsx)(n.code,{children:'@SuppressLint("STARVATION")'})," annotation, as follows:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:' import android.annotation.SuppressLint;\n\n @SuppressLint("STARVATION")\n public void m() {\n ...\n }\n'})}),"\n",(0,r.jsxs)(n.p,{children:["To signal to Infer that a method does not perform any blocking calls, despite\nappearences, you can use the ",(0,r.jsx)(n.code,{children:"@NonBlocking"})," annotation:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:" import com.facebook.infer.annotation.NonBlocking;\n\n @NonBlocking\n public void m() {\n ...\n }\n"})}),"\n",(0,r.jsxs)(n.p,{children:["This instructs Infer to filter out any potentially blocking calls in ",(0,r.jsx)(n.code,{children:"m()"}),"\n(also, transitively), and thus any other method can expect no starvation reports\ndue to a call to ",(0,r.jsx)(n.code,{children:"m()"}),". You will need to set up your class path appropriately to\ninclude the JAR files in ",(0,r.jsx)(n.code,{children:"infer/annotations"})," for this annotation to work."]}),"\n",(0,r.jsx)(n.h2,{id:"static_constructor_stall",children:"STATIC_CONSTRUCTOR_STALL"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#concurrency",children:"Concurrency"}),'. Reported as "Static Constructor Stall" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-static-constructor-stall-checker",children:"static-constructor-stall-checker"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"Calling certain methods, for instance dispatch_once, during the static initialization of objects is risky. It could cause deadlocks, because other objects might not have been initialized yet."}),"\n",(0,r.jsx)(n.h2,{id:"static_initialization_order_fiasco",children:"STATIC_INITIALIZATION_ORDER_FIASCO"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#memory-error",children:"Memory error"}),'. Reported as "Static Initialization Order Fiasco" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-siof",children:"siof"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This error is reported in C++. It fires when the initialization of a static\nvariable ",(0,r.jsx)(n.code,{children:"A"}),", accesses a static variable ",(0,r.jsx)(n.code,{children:"B"})," from another translation unit\n(usually another ",(0,r.jsx)(n.code,{children:".cpp"})," file). There are no guarantees whether ",(0,r.jsx)(n.code,{children:"B"})," has been\nalready initialized or not at that point."]}),"\n",(0,r.jsxs)(n.p,{children:["For more technical definition and techniques to avoid/remediate, see the\n",(0,r.jsx)(n.a,{href:"https://isocpp.org/wiki/faq/ctors#static-init-order",children:"FAQ"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"strict_mode_violation",children:"STRICT_MODE_VIOLATION"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#perf-regression",children:"Perf regression"}),'. Reported as "Strict Mode Violation" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-starvation",children:"starvation"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["Android has a feature called\n",(0,r.jsx)(n.a,{href:"https://developer.android.com/reference/android/os/StrictMode",children:"strict mode"}),",\nwhich if enabled, will flag the occasions where the main thread makes a call\nthat results in disk I/O, waiting on a network socket, etc. The analysis\ncatching starvation errors and deadlocks (the ",(0,r.jsx)(n.code,{children:"--starvation"})," analysis) has the\nability to statically detect such violations."]}),"\n",(0,r.jsxs)(n.p,{children:["To suppress this warning, it's enough to annotate the offending method with\n",(0,r.jsx)(n.code,{children:'@SuppressLint("STRICT_MODE_VIOLATION")'}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"strong_self_not_checked",children:"STRONG_SELF_NOT_CHECKED"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#memory-error",children:"Memory error"}),'. Reported as "StrongSelf Not Checked" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-self-in-block",children:"self-in-block"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This checks reports a potential issue when a block captures ",(0,r.jsx)(n.code,{children:"weakSelf"})," (a weak pointer to ",(0,r.jsx)(n.code,{children:"self"}),"),\nthen one assigns this pointer to a local variable ",(0,r.jsx)(n.code,{children:"strongSelf"})," inside the block and uses this variable\nwithout checking first whether it is ",(0,r.jsx)(n.code,{children:"nil"}),". The problem here is that the weak pointer could be ",(0,r.jsx)(n.code,{children:"nil"})," at\nthe time when the block is executed. So, the correct usage is to first check whether ",(0,r.jsx)(n.code,{children:"strongSelf"})," is a valid\npointer, and then use it."]}),"\n",(0,r.jsx)(n.p,{children:"Example:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objectivec",children:"__weak __typeof(self) weakSelf = self;\n int (^my_block)() = ^() {\n __strong __typeof(weakSelf) strongSelf = weakSelf;\n int y = strongSelf->x;\n ...\n"})}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"Action:"}),"\nAdd a check for ",(0,r.jsx)(n.code,{children:"nil"}),":"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objectivec",children:"__weak __typeof(self) weakSelf = self;\n int (^my_block)() = ^() {\n __strong __typeof(weakSelf) strongSelf = weakSelf;\n if (strongSelf) {\n int y = strongSelf->x;\n ...\n }\n"})}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.em,{children:"Limitations:"})," To keep this check simple and intra-procedural, we rely on names to find ",(0,r.jsx)(n.code,{children:"weakSelf"}),':\nwe assume that any captured weak pointer whose name contains "self" is a weak reference to ',(0,r.jsx)(n.code,{children:"self"}),".\nIn contrast, ",(0,r.jsx)(n.code,{children:"strongSelf"})," is a local variable to the block, so the check supports any name given to\na local strong pointer that has been assigned ",(0,r.jsx)(n.code,{children:"weakSelf"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"taint_error",children:"TAINT_ERROR"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#sensitive-data-flow",children:"Sensitive data flow"}),'. Reported as "Taint Error" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"A taint flow was detected from a source to a sink"}),"\n",(0,r.jsx)(n.h2,{id:"thread_safety_violation",children:"THREAD_SAFETY_VIOLATION"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#concurrency",children:"Concurrency"}),'. Reported as "Thread Safety Violation" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-racerd",children:"racerd"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This warning indicates a potential data race in Java. The analyser is called\nRacerD and this section gives brief but a mostly complete description of its\nfeatures. See the ",(0,r.jsx)(n.a,{href:"/docs/next/checker-racerd",children:"RacerD page"})," for more in-depth information and\nexamples."]}),"\n",(0,r.jsx)(n.h3,{id:"thread-safety-what-is-a-data-race",children:"Thread-safety: What is a data race"}),"\n",(0,r.jsx)(n.p,{children:"Here a data race is a pair of accesses to the same member field such that:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"at least one is a write, and,"}),"\n",(0,r.jsx)(n.li,{children:"at least one occurs without any lock synchronization, and,"}),"\n",(0,r.jsx)(n.li,{children:"the two accesses occur on threads (if known) which can run in parallel."}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"thread-safety-potential-fixes",children:"Thread-safety: Potential fixes"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["Synchronizing the accesses (using the ",(0,r.jsx)(n.code,{children:"synchronized"})," keyword, thread-exclusion\nsuch as atomic objects, ",(0,r.jsx)(n.code,{children:"volatile"})," etc)."]}),"\n",(0,r.jsx)(n.li,{children:"Making an offending method private -- this will exclude it from being checked\nat the top level, though it will be checked if called by a public method which\nmay itself, e.g., hold a lock when calling it."}),"\n",(0,r.jsxs)(n.li,{children:["Putting the two accesses on the same thread, e.g., by using ",(0,r.jsx)(n.code,{children:"@MainThread"})," or\n",(0,r.jsx)(n.code,{children:"@ThreadConfined"}),"."]}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"thread-safety-conditions-checked-before-reporting",children:"Thread-safety: Conditions checked before reporting"}),"\n",(0,r.jsxs)(n.p,{children:["The class and method are not marked ",(0,r.jsx)(n.code,{children:"@ThreadSafe(enableChecks = false)"}),", and,"]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["The method is declared ",(0,r.jsx)(n.code,{children:"synchronized"}),", or employs (non-transitively) locking,\nor,"]}),"\n",(0,r.jsxs)(n.li,{children:["The class is not marked ",(0,r.jsx)(n.code,{children:"@NotThreadSafe"}),", and,","\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["The class/method is marked ",(0,r.jsx)(n.code,{children:"@ThreadSafe,"})," or one of the configured synonyms\nin ",(0,r.jsx)(n.code,{children:".inferconfig"}),", or,"]}),"\n",(0,r.jsx)(n.li,{children:"A parent class, or an override method are marked with the above annotations."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:["NB currently RacerD ",(0,r.jsxs)(n.strong,{children:["does not take into account ",(0,r.jsx)(n.code,{children:"@GuardedBy"})]}),"."]}),"\n",(0,r.jsx)(n.h3,{id:"thread-safety-thread-annotations-recognized-by-racerd",children:"Thread-safety: Thread annotations recognized by RacerD"}),"\n",(0,r.jsxs)(n.p,{children:["These class and method annotations imply the method is on the main thread:\n",(0,r.jsx)(n.code,{children:"@MainThread"}),", ",(0,r.jsx)(n.code,{children:"@UiThread"})]}),"\n",(0,r.jsxs)(n.p,{children:["These method annotations imply the method is on the main thread: ",(0,r.jsx)(n.code,{children:"@OnBind"}),",\n",(0,r.jsx)(n.code,{children:"@OnEvent"}),", ",(0,r.jsx)(n.code,{children:"@OnMount"}),", ",(0,r.jsx)(n.code,{children:"@OnUnbind"}),", ",(0,r.jsx)(n.code,{children:"@OnUnmount"})]}),"\n",(0,r.jsx)(n.p,{children:"Both classes of annotations work through the inheritance tree (i.e. if a parent\nclass or method is marked with one of these annotations, so is the child class /\nmethod override)."}),"\n",(0,r.jsxs)(n.p,{children:["In addition to these, RacerD recognizes many lifecycle methods as necessarily\nrunning on the main thread, eg ",(0,r.jsx)(n.code,{children:"Fragment.onCreate"})," etc."]}),"\n",(0,r.jsxs)(n.p,{children:["Finally, the thread status of being on the main thread propagates backwards\nthrough the call graph (ie if ",(0,r.jsx)(n.code,{children:"foo"})," calls ",(0,r.jsx)(n.code,{children:"bar"})," and ",(0,r.jsx)(n.code,{children:"bar"})," is marked ",(0,r.jsx)(n.code,{children:"@UiThtread"}),"\nthen ",(0,r.jsx)(n.code,{children:"foo"})," is automatically considered on the main thread too). Calling\n",(0,r.jsx)(n.code,{children:"assertMainThread"}),", ",(0,r.jsx)(n.code,{children:"assertOnUiThread"}),", ",(0,r.jsx)(n.code,{children:"checkOnMainThread"})," has the same effect."]}),"\n",(0,r.jsxs)(n.p,{children:["NB RacerD currently ",(0,r.jsxs)(n.strong,{children:["does not recognize ",(0,r.jsx)(n.code,{children:"@WorkerThread"}),", ",(0,r.jsx)(n.code,{children:"@BinderThread"})," or\n",(0,r.jsx)(n.code,{children:"@AnyThread"})]}),"."]}),"\n",(0,r.jsx)(n.h3,{id:"thread-safety-other-annotations-and-what-they-do",children:"Thread-safety: Other annotations and what they do"}),"\n",(0,r.jsxs)(n.p,{children:["These annotations can be found at ",(0,r.jsx)(n.code,{children:"com.facebook.infer.annotation.*"}),"."]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"@Functional"})," This is a method annotation indicating the method always returns\nthe same value. When a method ",(0,r.jsx)(n.code,{children:"foo"})," is annotated ",(0,r.jsx)(n.code,{children:"@Functional"}),", RacerD will\nignore any writes of the return value of ",(0,r.jsx)(n.code,{children:"foo"}),". For example, in\n",(0,r.jsx)(n.code,{children:"this.x = foo()"}),", the write to ",(0,r.jsx)(n.code,{children:"this.x"})," is ignored. The reasoning is that if\nthe method returns the same value whenever it's called, any data race on\n",(0,r.jsx)(n.code,{children:"this.x"})," is benign, if that is the only write."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"@ThreadConfined"})," This is a class/method/field annotation which takes a single\nparameter which can be ",(0,r.jsx)(n.code,{children:"UI"}),", ",(0,r.jsx)(n.code,{children:"ANY"})," or a user chosen string. It indicates to\nRacerD a thread identifier for the class/method/field. Thus,\n",(0,r.jsx)(n.code,{children:"@ThreadConfined(UI)"})," is equivalent to ",(0,r.jsx)(n.code,{children:"@UiThread"}),", and ",(0,r.jsx)(n.code,{children:"@ThreadConfined(ANY)"}),"\nis equivalent to not having the annotation at all, for classes and methods.\nWhen this annotation is applied to a field it instructs Infer to assume\n(without checking) that all accesses to that field are made on the same thread\n(and can, therefore, not race by definition). The intention is that RacerD\nuses that to detect exclusion between accesses occurring on the same thread.\nHowever, only the UI thread is supported at this time, and any user provided\nvalue is considered equal to ",(0,r.jsx)(n.code,{children:"UI"}),"."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"@VisibleForTesting"})," A method annotation making Infer consider the method as\neffectively ",(0,r.jsx)(n.code,{children:"private"}),". This means it will not be checked for races against\nother non-private methods of the class, but only if called by one."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"@ReturnsOwnership"})," A method annotation indicating that the method returns a\nfreshly owned object. Accesses to the returned value will not be considered\nfor data races, as the object is in-effect unique and not accessible yet from\nother threads. The main utility of this annotation is in interfaces, where\nInfer cannot look up the implementation and decide for itself."]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"topl_error",children:"TOPL_ERROR"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#user-defined-property",children:"User defined property"}),'. Reported as "Topl Error" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-topl",children:"topl"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"A violation of a Topl property (user-specified).\nThere is an execution path in the code that drives a Topl property from a start state to an error state."}),"\n",(0,r.jsx)(n.p,{children:"This indicates that the code has a user-defined undesired behavior."}),"\n",(0,r.jsxs)(n.p,{children:["See ",(0,r.jsx)(n.a,{href:"/docs/next/checker-topl#what-is-it",children:"Topl"})," for an example"]}),"\n",(0,r.jsx)(n.h2,{id:"topl_error_latent",children:"TOPL_ERROR_LATENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#user-defined-property",children:"User defined property"}),'. Reported as "Topl Error Latent" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-topl",children:"topl"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A latent ",(0,r.jsx)(n.a,{href:"#topl_error",children:"TOPL_ERROR"}),". See the ",(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse#latent-issues",children:"documentation on Pulse latent issues"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"use_after_delete",children:"USE_AFTER_DELETE"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#memory-error",children:"Memory error"}),'. Reported as "Use After Delete" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["An address that was invalidated by a call to ",(0,r.jsx)(n.code,{children:"delete"})," in C++ is dereferenced."]}),"\n",(0,r.jsx)(n.h2,{id:"use_after_delete_latent",children:"USE_AFTER_DELETE_LATENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#memory-error",children:"Memory error"}),'. Reported as "Use After Delete Latent" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A latent ",(0,r.jsx)(n.a,{href:"#use_after_delete",children:"USE_AFTER_DELETE"}),". See the ",(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse#latent-issues",children:"documentation on Pulse latent issues"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"use_after_free",children:"USE_AFTER_FREE"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#memory-error",children:"Memory error"}),'. Reported as "Use After Free" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["An address that was invalidated by a call to ",(0,r.jsx)(n.code,{children:"free"})," in C is dereferenced."]}),"\n",(0,r.jsx)(n.h2,{id:"use_after_free_latent",children:"USE_AFTER_FREE_LATENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#memory-error",children:"Memory error"}),'. Reported as "Use After Free Latent" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A latent ",(0,r.jsx)(n.a,{href:"#use_after_free",children:"USE_AFTER_FREE"}),". See the ",(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse#latent-issues",children:"documentation on Pulse latent issues"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"use_after_lifetime",children:"USE_AFTER_LIFETIME"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#memory-error",children:"Memory error"}),'. Reported as "Use After Lifetime" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsx)(n.p,{children:"The lifetime of an object has ended but that object is being\naccessed. For example, the address of a variable holding a C++ object\nis accessed after the variable has gone out of scope:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-cpp",children:"void foo() {\n X* p;\n { // new scope\n X x = X();\n p = &x;\n } // x has gone out of scope\n p->method(); // ERROR: you should not access *p after x has gone out of scope\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"use_after_lifetime_latent",children:"USE_AFTER_LIFETIME_LATENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#memory-error",children:"Memory error"}),'. Reported as "Use After Lifetime Latent" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A latent ",(0,r.jsx)(n.a,{href:"#use_after_lifetime",children:"USE_AFTER_LIFETIME"}),". See the ",(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse#latent-issues",children:"documentation on Pulse latent issues"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"vector_invalidation",children:"VECTOR_INVALIDATION"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#memory-error",children:"Memory error"}),'. Reported as "Vector Invalidation" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["An address pointing into a C++ ",(0,r.jsx)(n.code,{children:"std::vector"})," might have become\ninvalid. This can happen when an address is taken into a vector, then\nthe vector is mutated in a way that might invalidate the address, for\nexample by adding elements to the vector, which might trigger a\nre-allocation of the entire vector contents (thereby invalidating the\npointers into the previous location of the contents)."]}),"\n",(0,r.jsx)(n.p,{children:"For example:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-cpp",children:'void deref_vector_element_after_push_back_bad(std::vector& vec) {\n int* elt = &vec[1];\n int* y = elt;\n vec.push_back(42); // if the array backing the vector was full already, this\n // will re-allocate it and copy the previous contents\n // into the new array, then delete the previous array\n std::cout << *y << "\\n"; // bad: y might be invalid\n}\n'})}),"\n",(0,r.jsx)(n.h2,{id:"vector_invalidation_latent",children:"VECTOR_INVALIDATION_LATENT"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:["Category: ",(0,r.jsx)(n.a,{href:"/docs/next/all-categories#memory-error",children:"Memory error"}),'. Reported as "Vector Invalidation Latent" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse",children:"pulse"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["A latent ",(0,r.jsx)(n.a,{href:"#vector_invalidation",children:"VECTOR_INVALIDATION"}),". See the ",(0,r.jsx)(n.a,{href:"/docs/next/checker-pulse#latent-issues",children:"documentation on Pulse latent issues"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"weak_self_in_no_escape_block",children:"WEAK_SELF_IN_NO_ESCAPE_BLOCK"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.em,{children:['Reported as "Weak Self In No Escape Block" by ',(0,r.jsx)(n.a,{href:"/docs/next/checker-self-in-block",children:"self-in-block"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["This check reports when ",(0,r.jsx)(n.code,{children:"weakSelf"})," (a weak pointer to ",(0,r.jsx)(n.code,{children:"self"}),') is used in\na block, and this block is passed to a "no escaping" method. This means that\nthe block passed to that method won\'t be leaving the current scope, this is\nmarked with the annotation ',(0,r.jsx)(n.code,{children:"NS_NOESCAPE"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:['The issue here is that, because the block is "no escaping", there is no need to use\n',(0,r.jsx)(n.code,{children:"weakSelf"})," and ",(0,r.jsx)(n.code,{children:"strongSelf"})," but we can just use ",(0,r.jsx)(n.code,{children:"self"}),". This has the advantage of\nnot needing to deal with the added complexity of weak pointers, and it simplifies the\ncode."]}),"\n",(0,r.jsx)(n.p,{children:"Example:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objectivec",children:" __weak __typeof(self) weakSelf = self;\n [self foo:^() { //foo's first parameter is annotates with `NS_NOESCAPE`\n [weakSelf bar];\n }];\n"})}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"Action"}),":"]}),"\n",(0,r.jsxs)(n.p,{children:["Replace ",(0,r.jsx)(n.code,{children:"weakSelf"})," with ",(0,r.jsx)(n.code,{children:"self"}),":"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-objectivec",children:" [self foo:^() {\n [self bar];\n }];\n"})}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.em,{children:"Limitations:"})," To keep this check simple and intra-procedural, we rely on names to find ",(0,r.jsx)(n.code,{children:"weakSelf"}),':\nwe assume that any captured weak pointer whose name contains "self" is a weak reference to ',(0,r.jsx)(n.code,{children:"self"}),"."]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},8453:(e,n,s)=>{s.d(n,{R:()=>a,x:()=>l});var r=s(6540);const i={},t=r.createContext(i);function a(e){const n=r.useContext(t);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),r.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/runtime~main.bf22b583.js b/assets/js/runtime~main.f2ef44c5.js similarity index 97% rename from assets/js/runtime~main.bf22b583.js rename to assets/js/runtime~main.f2ef44c5.js index 08f83ffd247..72dff7a6d74 100644 --- a/assets/js/runtime~main.bf22b583.js +++ b/assets/js/runtime~main.f2ef44c5.js @@ -1 +1 @@ -(()=>{"use strict";var a,e,f,c,d={},b={};function r(a){var e=b[a];if(void 0!==e)return e.exports;var f=b[a]={exports:{}};return d[a].call(f.exports,f,f.exports,r),f.exports}r.m=d,a=[],r.O=(e,f,c,d)=>{if(!f){var b=1/0;for(i=0;i=d)&&Object.keys(r.O).every((a=>r.O[a](f[o])))?f.splice(o--,1):(t=!1,d0&&a[i-1][2]>d;i--)a[i]=a[i-1];a[i]=[f,c,d]},r.n=a=>{var e=a&&a.__esModule?()=>a.default:()=>a;return r.d(e,{a:e}),e},f=Object.getPrototypeOf?a=>Object.getPrototypeOf(a):a=>a.__proto__,r.t=function(a,c){if(1&c&&(a=this(a)),8&c)return a;if("object"==typeof a&&a){if(4&c&&a.__esModule)return a;if(16&c&&"function"==typeof a.then)return a}var d=Object.create(null);r.r(d);var b={};e=e||[null,f({}),f([]),f(f)];for(var t=2&c&&a;"object"==typeof t&&!~e.indexOf(t);t=f(t))Object.getOwnPropertyNames(t).forEach((e=>b[e]=()=>a[e]));return b.default=()=>a,r.d(d,b),d},r.d=(a,e)=>{for(var f in e)r.o(e,f)&&!r.o(a,f)&&Object.defineProperty(a,f,{enumerable:!0,get:e[f]})},r.f={},r.e=a=>Promise.all(Object.keys(r.f).reduce(((e,f)=>(r.f[f](a,e),e)),[])),r.u=a=>"assets/js/"+({46:"b05ccea0",100:"57bcddd6",293:"ac4b567d",411:"7f661f82",457:"4cccfac9",468:"34fbd09a",485:"7b1f0035",492:"61eca9d6",517:"f8092feb",530:"58972da3",553:"a373fd77",613:"acaf655c",659:"3c055f5e",700:"5aef2ce6",741:"3423820d",777:"56ebd09a",849:"0058b4c6",881:"71a2656f",946:"884bd1d2",957:"c141421f",1010:"aa0b35eb",1068:"bbdc39ec",1158:"8919ea97",1235:"a7456010",1236:"e436f9fb",1279:"21a9d6ed",1410:"a8248417",1416:"d9e16301",1439:"c8131338",1444:"9d221b96",1463:"be77d225",1533:"33776668",1599:"abc9d724",1610:"b9f8aa82",1652:"6297ff83",1734:"a33b6a74",1759:"89b1f439",1822:"4dac5fec",1847:"f28f39ea",1903:"acecf23e",1926:"3eb0a99f",1932:"7a64ca81",1989:"a5a260f1",1998:"06d8773d",2032:"21614072",2057:"cd3b4295",2138:"1a4e3797",2212:"bf6aacca",2316:"c359af60",2365:"ae894706",2380:"ae565638",2385:"e44e3f47",2509:"6d752ef5",2634:"c4f5d8e4",2708:"9d4bdb35",2711:"9e4087bc",2740:"65dc7644",2883:"8a838ea0",2938:"d47ba782",2968:"a02168a2",2996:"8a061d83",3157:"3c653e3b",3212:"76c96f4d",3249:"ccc49370",3426:"9258f162",3487:"7b6b5c72",3526:"4c2546f9",3548:"6021085e",3699:"1772b9c1",3716:"eb0c92c1",3730:"70793eb2",3838:"a67edc69",3967:"5a5dcc21",4215:"3a27b2d9",4235:"00d3276d",4261:"5bb07cf5",4341:"e0f83a1d",4478:"8fb47bcc",4515:"937dc5a6",4569:"e6b9ef91",4631:"a2bed8f0",4638:"bd470307",4721:"812c592f",4728:"671939c9",4765:"c412bf64",4865:"79263788",4883:"491a3217",4982:"e9325e77",5041:"5573af76",5073:"fd7416f6",5075:"c8a5dae5",5118:"bf769997",5277:"0346afaa",5360:"420497a2",5386:"3c741b47",5543:"81cc3644",5632:"1d8647da",5680:"7efbfa7e",5742:"aba21aa0",6096:"25a5a20c",6107:"16fe8a4c",6112:"f22cd6c1",6146:"da41ed28",6166:"57dd985e",6227:"3a3b1bdb",6230:"38f5dda4",6231:"293e08e8",6237:"f5ff54f0",6241:"509dc7bf",6408:"aaff9110",6499:"b4a56aa4",6510:"fa38ac94",6555:"b388a56e",6629:"64f1f19c",6689:"58de4400",6929:"fa9ab54d",6950:"0c0efcaa",7017:"ca86781b",7098:"a7bd4aaa",7197:"5f403532",7207:"00e87d9a",7211:"0774da3f",7283:"a3e198d1",7314:"1df9637e",7318:"4b970726",7323:"7f18f0db",7331:"136023f9",7343:"1ed7bad6",7378:"04f8d6af",7417:"637f8365",7419:"ab17452f",7436:"bc20efef",7472:"814f3328",7560:"bab022f4",7586:"45d37095",7632:"b065408b",7643:"a6aa9e1f",7698:"cd83de9e",7709:"64cca8ef",7758:"f28ca027",7773:"184ad633",7803:"df12ff2a",7877:"3eac2097",7906:"f769b3fd",7930:"7dd0d394",7972:"acb2d06a",8045:"041e4035",8108:"aaa764ed",8112:"bc3f1a98",8130:"f81c1134",8146:"c15d9823",8283:"37d3b766",8301:"4f53e586",8401:"17896441",8405:"5acb8db5",8500:"e66621bc",8680:"3d9729af",8684:"c26add1d",8822:"3f2a1ecb",8886:"413f2abb",8973:"1dbe42a7",8984:"99c7964b",9023:"1fdfdeaa",9026:"5c708541",9034:"b7bf8e49",9048:"a94703ab",9088:"18328e9e",9095:"cf554d4e",9262:"d1458f14",9366:"0fe8a02a",9383:"223037ba",9390:"c222a988",9401:"a177ae00",9420:"0c78c462",9437:"8fdeae25",9525:"bf1307fc",9640:"9702a600",9647:"5e95c892",9676:"e305a15c",9677:"556d04db",9692:"1906a68b",9749:"8db808e7",9820:"4fb08289",9858:"36994c47",9978:"1c7a9c9f"}[a]||a)+"."+{46:"b2cb9ba6",100:"7e504885",293:"d04b5583",411:"9f54fe23",416:"b444750d",457:"10781a2e",468:"0b6da666",485:"84560a9e",492:"27add587",517:"45da7e6b",530:"144b1897",553:"cd1fb531",613:"eb6448cb",659:"c9fee1c3",700:"60ce27e3",741:"ea770bb6",777:"0c8134d7",849:"e2f8f141",881:"22df8c25",946:"c3a6acde",957:"9a903d38",1010:"f4ed61f6",1068:"43afbcfd",1158:"7896e2fd",1235:"7e3226f2",1236:"d2432c58",1279:"80187f24",1410:"f12afd1b",1416:"99a75473",1439:"a2fef71a",1444:"8b4ff73f",1463:"b6366ec4",1533:"1e84a12d",1599:"433f01d0",1610:"26b69d02",1652:"ac2d38d7",1734:"bc321def",1759:"5b60b603",1822:"b053f13c",1847:"a016e3c4",1903:"3eef8a98",1926:"3c9f37cb",1932:"c274d3ab",1989:"f642cec3",1998:"399aff17",2032:"6066b791",2057:"4e2f5182",2138:"9a1f1807",2212:"35ad86e9",2237:"fdb00234",2316:"1278ce61",2365:"81c60e92",2380:"6ab36f60",2385:"75eba3eb",2509:"0bd22b04",2634:"25763f5c",2708:"40b0336b",2711:"1081de11",2740:"c4295ab5",2883:"d4259207",2938:"ad0784b3",2968:"c12dfb67",2996:"a2812d5a",3157:"1a485114",3212:"569557e5",3249:"28189709",3426:"6f760b9c",3487:"455be240",3526:"d30dc19e",3548:"d9150b94",3699:"6bf2e57d",3716:"4e7df13b",3730:"22f027bd",3838:"1001aa09",3962:"52e2266e",3967:"693ecffd",4215:"c7e85dcd",4235:"cad11f73",4261:"20d299eb",4341:"4b69d034",4478:"84c3c61a",4515:"32551d95",4569:"ec74b673",4631:"363bd2ea",4638:"0413a1ba",4721:"aff6270b",4728:"f5aac289",4765:"8ff827fe",4865:"d5a31d4b",4883:"d4d1ae39",4982:"2a9e7126",5041:"568cdecb",5073:"4ae8f342",5075:"a0ba9bb5",5118:"1fa7cc3d",5277:"b3c3fd48",5360:"2011b81d",5386:"96e959b4",5543:"ccae926e",5632:"c432d9e3",5680:"e65a1f00",5742:"0aa4e8d5",6096:"e78589bb",6107:"0eb550b3",6112:"49c4901a",6146:"6c1a90fd",6166:"a29cb4d7",6227:"518da510",6230:"cedc7aba",6231:"c6941bee",6237:"4ca96c24",6238:"29a1b222",6241:"6a3d89bc",6408:"11519136",6499:"f86e56c3",6510:"410e9623",6555:"c99fd548",6629:"872a0fc0",6689:"8585eca6",6929:"96176fab",6950:"c5f5b6c5",7017:"20ee549e",7098:"664e8c83",7197:"bba25bff",7207:"ef765681",7211:"61723255",7283:"10f69968",7314:"d3e87582",7318:"32fb9336",7323:"27c4044f",7331:"7d417834",7343:"c6e0943c",7378:"c08c57a3",7417:"91ff7f1a",7419:"ae848db9",7436:"283b9ce1",7472:"7a062e80",7560:"6084716d",7586:"9862a2cf",7632:"a20f5cc6",7643:"6b9a26f5",7698:"beb22e5d",7709:"a45faa55",7758:"0b9ad65b",7773:"240342b6",7803:"4d76c75b",7877:"2a2c61e7",7906:"795aa392",7930:"6924f01e",7972:"2a6a82d3",8045:"b69a3096",8108:"15e2a19c",8112:"f88f3e24",8130:"cc174e15",8146:"047496b9",8158:"cfa83e34",8283:"0b0d66d2",8301:"a5671cc6",8401:"0f17bec8",8405:"12015b5c",8500:"c5f2ec17",8680:"df738802",8684:"d8ca081e",8822:"dfb31018",8886:"2a3134f2",8913:"b6f04e6e",8973:"ac57b1d6",8984:"ef715b7b",9023:"678fc887",9026:"6ca14753",9034:"fe974b18",9048:"15908900",9088:"b1d20ec4",9095:"32b19eb1",9262:"a7b41027",9366:"4fdeaedd",9383:"2aa7902c",9390:"f2ba5f8b",9401:"6bc20c68",9420:"88d0615d",9437:"904d52c1",9525:"a6567380",9640:"b1b54438",9647:"b2f2604d",9676:"9f747501",9677:"d65448fc",9692:"f6bbe8eb",9749:"940e50fa",9820:"c072ae0c",9858:"72bbc0ce",9978:"dee77249"}[a]+".js",r.miniCssF=a=>{},r.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(a){if("object"==typeof window)return window}}(),r.o=(a,e)=>Object.prototype.hasOwnProperty.call(a,e),c={},r.l=(a,e,f,d)=>{if(c[a])c[a].push(e);else{var b,t;if(void 0!==f)for(var o=document.getElementsByTagName("script"),n=0;n{b.onerror=b.onload=null,clearTimeout(l);var d=c[a];if(delete c[a],b.parentNode&&b.parentNode.removeChild(b),d&&d.forEach((a=>a(f))),e)return e(f)},l=setTimeout(u.bind(null,void 0,{type:"timeout",target:b}),12e4);b.onerror=u.bind(null,b.onerror),b.onload=u.bind(null,b.onload),t&&document.head.appendChild(b)}},r.r=a=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(a,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(a,"__esModule",{value:!0})},r.p="/",r.gca=function(a){return a={17896441:"8401",21614072:"2032",33776668:"1533",79263788:"4865",b05ccea0:"46","57bcddd6":"100",ac4b567d:"293","7f661f82":"411","4cccfac9":"457","34fbd09a":"468","7b1f0035":"485","61eca9d6":"492",f8092feb:"517","58972da3":"530",a373fd77:"553",acaf655c:"613","3c055f5e":"659","5aef2ce6":"700","3423820d":"741","56ebd09a":"777","0058b4c6":"849","71a2656f":"881","884bd1d2":"946",c141421f:"957",aa0b35eb:"1010",bbdc39ec:"1068","8919ea97":"1158",a7456010:"1235",e436f9fb:"1236","21a9d6ed":"1279",a8248417:"1410",d9e16301:"1416",c8131338:"1439","9d221b96":"1444",be77d225:"1463",abc9d724:"1599",b9f8aa82:"1610","6297ff83":"1652",a33b6a74:"1734","89b1f439":"1759","4dac5fec":"1822",f28f39ea:"1847",acecf23e:"1903","3eb0a99f":"1926","7a64ca81":"1932",a5a260f1:"1989","06d8773d":"1998",cd3b4295:"2057","1a4e3797":"2138",bf6aacca:"2212",c359af60:"2316",ae894706:"2365",ae565638:"2380",e44e3f47:"2385","6d752ef5":"2509",c4f5d8e4:"2634","9d4bdb35":"2708","9e4087bc":"2711","65dc7644":"2740","8a838ea0":"2883",d47ba782:"2938",a02168a2:"2968","8a061d83":"2996","3c653e3b":"3157","76c96f4d":"3212",ccc49370:"3249","9258f162":"3426","7b6b5c72":"3487","4c2546f9":"3526","6021085e":"3548","1772b9c1":"3699",eb0c92c1:"3716","70793eb2":"3730",a67edc69:"3838","5a5dcc21":"3967","3a27b2d9":"4215","00d3276d":"4235","5bb07cf5":"4261",e0f83a1d:"4341","8fb47bcc":"4478","937dc5a6":"4515",e6b9ef91:"4569",a2bed8f0:"4631",bd470307:"4638","812c592f":"4721","671939c9":"4728",c412bf64:"4765","491a3217":"4883",e9325e77:"4982","5573af76":"5041",fd7416f6:"5073",c8a5dae5:"5075",bf769997:"5118","0346afaa":"5277","420497a2":"5360","3c741b47":"5386","81cc3644":"5543","1d8647da":"5632","7efbfa7e":"5680",aba21aa0:"5742","25a5a20c":"6096","16fe8a4c":"6107",f22cd6c1:"6112",da41ed28:"6146","57dd985e":"6166","3a3b1bdb":"6227","38f5dda4":"6230","293e08e8":"6231",f5ff54f0:"6237","509dc7bf":"6241",aaff9110:"6408",b4a56aa4:"6499",fa38ac94:"6510",b388a56e:"6555","64f1f19c":"6629","58de4400":"6689",fa9ab54d:"6929","0c0efcaa":"6950",ca86781b:"7017",a7bd4aaa:"7098","5f403532":"7197","00e87d9a":"7207","0774da3f":"7211",a3e198d1:"7283","1df9637e":"7314","4b970726":"7318","7f18f0db":"7323","136023f9":"7331","1ed7bad6":"7343","04f8d6af":"7378","637f8365":"7417",ab17452f:"7419",bc20efef:"7436","814f3328":"7472",bab022f4:"7560","45d37095":"7586",b065408b:"7632",a6aa9e1f:"7643",cd83de9e:"7698","64cca8ef":"7709",f28ca027:"7758","184ad633":"7773",df12ff2a:"7803","3eac2097":"7877",f769b3fd:"7906","7dd0d394":"7930",acb2d06a:"7972","041e4035":"8045",aaa764ed:"8108",bc3f1a98:"8112",f81c1134:"8130",c15d9823:"8146","37d3b766":"8283","4f53e586":"8301","5acb8db5":"8405",e66621bc:"8500","3d9729af":"8680",c26add1d:"8684","3f2a1ecb":"8822","413f2abb":"8886","1dbe42a7":"8973","99c7964b":"8984","1fdfdeaa":"9023","5c708541":"9026",b7bf8e49:"9034",a94703ab:"9048","18328e9e":"9088",cf554d4e:"9095",d1458f14:"9262","0fe8a02a":"9366","223037ba":"9383",c222a988:"9390",a177ae00:"9401","0c78c462":"9420","8fdeae25":"9437",bf1307fc:"9525","9702a600":"9640","5e95c892":"9647",e305a15c:"9676","556d04db":"9677","1906a68b":"9692","8db808e7":"9749","4fb08289":"9820","36994c47":"9858","1c7a9c9f":"9978"}[a]||a,r.p+r.u(a)},(()=>{var a={5354:0,1869:0};r.f.j=(e,f)=>{var c=r.o(a,e)?a[e]:void 0;if(0!==c)if(c)f.push(c[2]);else if(/^(1869|5354)$/.test(e))a[e]=0;else{var d=new Promise(((f,d)=>c=a[e]=[f,d]));f.push(c[2]=d);var b=r.p+r.u(e),t=new Error;r.l(b,(f=>{if(r.o(a,e)&&(0!==(c=a[e])&&(a[e]=void 0),c)){var d=f&&("load"===f.type?"missing":f.type),b=f&&f.target&&f.target.src;t.message="Loading chunk "+e+" failed.\n("+d+": "+b+")",t.name="ChunkLoadError",t.type=d,t.request=b,c[1](t)}}),"chunk-"+e,e)}},r.O.j=e=>0===a[e];var e=(e,f)=>{var c,d,b=f[0],t=f[1],o=f[2],n=0;if(b.some((e=>0!==a[e]))){for(c in t)r.o(t,c)&&(r.m[c]=t[c]);if(o)var i=o(r)}for(e&&e(f);n{"use strict";var a,e,f,c,d={},b={};function r(a){var e=b[a];if(void 0!==e)return e.exports;var f=b[a]={exports:{}};return d[a].call(f.exports,f,f.exports,r),f.exports}r.m=d,a=[],r.O=(e,f,c,d)=>{if(!f){var b=1/0;for(i=0;i=d)&&Object.keys(r.O).every((a=>r.O[a](f[o])))?f.splice(o--,1):(t=!1,d0&&a[i-1][2]>d;i--)a[i]=a[i-1];a[i]=[f,c,d]},r.n=a=>{var e=a&&a.__esModule?()=>a.default:()=>a;return r.d(e,{a:e}),e},f=Object.getPrototypeOf?a=>Object.getPrototypeOf(a):a=>a.__proto__,r.t=function(a,c){if(1&c&&(a=this(a)),8&c)return a;if("object"==typeof a&&a){if(4&c&&a.__esModule)return a;if(16&c&&"function"==typeof a.then)return a}var d=Object.create(null);r.r(d);var b={};e=e||[null,f({}),f([]),f(f)];for(var t=2&c&&a;"object"==typeof t&&!~e.indexOf(t);t=f(t))Object.getOwnPropertyNames(t).forEach((e=>b[e]=()=>a[e]));return b.default=()=>a,r.d(d,b),d},r.d=(a,e)=>{for(var f in e)r.o(e,f)&&!r.o(a,f)&&Object.defineProperty(a,f,{enumerable:!0,get:e[f]})},r.f={},r.e=a=>Promise.all(Object.keys(r.f).reduce(((e,f)=>(r.f[f](a,e),e)),[])),r.u=a=>"assets/js/"+({46:"b05ccea0",100:"57bcddd6",293:"ac4b567d",411:"7f661f82",457:"4cccfac9",468:"34fbd09a",485:"7b1f0035",492:"61eca9d6",517:"f8092feb",530:"58972da3",553:"a373fd77",613:"acaf655c",659:"3c055f5e",700:"5aef2ce6",741:"3423820d",777:"56ebd09a",849:"0058b4c6",881:"71a2656f",946:"884bd1d2",957:"c141421f",1010:"aa0b35eb",1068:"bbdc39ec",1158:"8919ea97",1235:"a7456010",1236:"e436f9fb",1279:"21a9d6ed",1410:"a8248417",1416:"d9e16301",1439:"c8131338",1444:"9d221b96",1463:"be77d225",1533:"33776668",1599:"abc9d724",1610:"b9f8aa82",1652:"6297ff83",1734:"a33b6a74",1759:"89b1f439",1822:"4dac5fec",1847:"f28f39ea",1903:"acecf23e",1926:"3eb0a99f",1932:"7a64ca81",1989:"a5a260f1",1998:"06d8773d",2032:"21614072",2057:"cd3b4295",2138:"1a4e3797",2212:"bf6aacca",2316:"c359af60",2365:"ae894706",2380:"ae565638",2385:"e44e3f47",2509:"6d752ef5",2634:"c4f5d8e4",2708:"9d4bdb35",2711:"9e4087bc",2740:"65dc7644",2883:"8a838ea0",2938:"d47ba782",2968:"a02168a2",2996:"8a061d83",3157:"3c653e3b",3212:"76c96f4d",3249:"ccc49370",3426:"9258f162",3487:"7b6b5c72",3526:"4c2546f9",3548:"6021085e",3699:"1772b9c1",3716:"eb0c92c1",3730:"70793eb2",3838:"a67edc69",3967:"5a5dcc21",4215:"3a27b2d9",4235:"00d3276d",4261:"5bb07cf5",4341:"e0f83a1d",4478:"8fb47bcc",4515:"937dc5a6",4569:"e6b9ef91",4631:"a2bed8f0",4638:"bd470307",4721:"812c592f",4728:"671939c9",4765:"c412bf64",4865:"79263788",4883:"491a3217",4982:"e9325e77",5041:"5573af76",5073:"fd7416f6",5075:"c8a5dae5",5118:"bf769997",5277:"0346afaa",5360:"420497a2",5386:"3c741b47",5543:"81cc3644",5632:"1d8647da",5680:"7efbfa7e",5742:"aba21aa0",6096:"25a5a20c",6107:"16fe8a4c",6112:"f22cd6c1",6146:"da41ed28",6166:"57dd985e",6227:"3a3b1bdb",6230:"38f5dda4",6231:"293e08e8",6237:"f5ff54f0",6241:"509dc7bf",6408:"aaff9110",6499:"b4a56aa4",6510:"fa38ac94",6555:"b388a56e",6629:"64f1f19c",6689:"58de4400",6929:"fa9ab54d",6950:"0c0efcaa",7017:"ca86781b",7098:"a7bd4aaa",7197:"5f403532",7207:"00e87d9a",7211:"0774da3f",7283:"a3e198d1",7314:"1df9637e",7318:"4b970726",7323:"7f18f0db",7331:"136023f9",7343:"1ed7bad6",7378:"04f8d6af",7417:"637f8365",7419:"ab17452f",7436:"bc20efef",7472:"814f3328",7560:"bab022f4",7586:"45d37095",7632:"b065408b",7643:"a6aa9e1f",7698:"cd83de9e",7709:"64cca8ef",7758:"f28ca027",7773:"184ad633",7803:"df12ff2a",7877:"3eac2097",7906:"f769b3fd",7930:"7dd0d394",7972:"acb2d06a",8045:"041e4035",8108:"aaa764ed",8112:"bc3f1a98",8130:"f81c1134",8146:"c15d9823",8283:"37d3b766",8301:"4f53e586",8401:"17896441",8405:"5acb8db5",8500:"e66621bc",8680:"3d9729af",8684:"c26add1d",8822:"3f2a1ecb",8886:"413f2abb",8973:"1dbe42a7",8984:"99c7964b",9023:"1fdfdeaa",9026:"5c708541",9034:"b7bf8e49",9048:"a94703ab",9088:"18328e9e",9095:"cf554d4e",9262:"d1458f14",9366:"0fe8a02a",9383:"223037ba",9390:"c222a988",9401:"a177ae00",9420:"0c78c462",9437:"8fdeae25",9525:"bf1307fc",9640:"9702a600",9647:"5e95c892",9676:"e305a15c",9677:"556d04db",9692:"1906a68b",9749:"8db808e7",9820:"4fb08289",9858:"36994c47",9978:"1c7a9c9f"}[a]||a)+"."+{46:"b2cb9ba6",100:"7e504885",293:"d04b5583",411:"9f54fe23",416:"b444750d",457:"10781a2e",468:"0b6da666",485:"84560a9e",492:"27add587",517:"45da7e6b",530:"144b1897",553:"cd1fb531",613:"eb6448cb",659:"c9fee1c3",700:"60ce27e3",741:"ea770bb6",777:"0c8134d7",849:"e2f8f141",881:"22df8c25",946:"c3a6acde",957:"9a903d38",1010:"f4ed61f6",1068:"43afbcfd",1158:"7896e2fd",1235:"7e3226f2",1236:"d2432c58",1279:"80187f24",1410:"f12afd1b",1416:"99a75473",1439:"a2fef71a",1444:"8b4ff73f",1463:"b6366ec4",1533:"1e84a12d",1599:"433f01d0",1610:"26b69d02",1652:"ac2d38d7",1734:"bc321def",1759:"5b60b603",1822:"b053f13c",1847:"a016e3c4",1903:"3eef8a98",1926:"3c9f37cb",1932:"c274d3ab",1989:"f642cec3",1998:"399aff17",2032:"6066b791",2057:"4e2f5182",2138:"9a1f1807",2212:"35ad86e9",2237:"fdb00234",2316:"87765c92",2365:"81c60e92",2380:"6ab36f60",2385:"75eba3eb",2509:"0bd22b04",2634:"25763f5c",2708:"40b0336b",2711:"1081de11",2740:"c4295ab5",2883:"d4259207",2938:"ad0784b3",2968:"c12dfb67",2996:"a2812d5a",3157:"1a485114",3212:"569557e5",3249:"28189709",3426:"6f760b9c",3487:"455be240",3526:"d30dc19e",3548:"d9150b94",3699:"6bf2e57d",3716:"4e7df13b",3730:"22f027bd",3838:"1001aa09",3962:"52e2266e",3967:"693ecffd",4215:"c7e85dcd",4235:"cad11f73",4261:"20d299eb",4341:"4b69d034",4478:"84c3c61a",4515:"32551d95",4569:"ec74b673",4631:"363bd2ea",4638:"0413a1ba",4721:"aff6270b",4728:"f5aac289",4765:"8ff827fe",4865:"d5a31d4b",4883:"d4d1ae39",4982:"2a9e7126",5041:"568cdecb",5073:"4ae8f342",5075:"a0ba9bb5",5118:"1fa7cc3d",5277:"b3c3fd48",5360:"2011b81d",5386:"96e959b4",5543:"ccae926e",5632:"c432d9e3",5680:"e65a1f00",5742:"0aa4e8d5",6096:"e78589bb",6107:"0eb550b3",6112:"49c4901a",6146:"6c1a90fd",6166:"a29cb4d7",6227:"518da510",6230:"cedc7aba",6231:"c6941bee",6237:"4ca96c24",6238:"29a1b222",6241:"6a3d89bc",6408:"11519136",6499:"f86e56c3",6510:"410e9623",6555:"c99fd548",6629:"872a0fc0",6689:"8585eca6",6929:"96176fab",6950:"c5f5b6c5",7017:"20ee549e",7098:"664e8c83",7197:"bba25bff",7207:"ef765681",7211:"61723255",7283:"10f69968",7314:"d3e87582",7318:"32fb9336",7323:"27c4044f",7331:"7d417834",7343:"c6e0943c",7378:"c08c57a3",7417:"91ff7f1a",7419:"ae848db9",7436:"283b9ce1",7472:"7a062e80",7560:"6084716d",7586:"9862a2cf",7632:"a20f5cc6",7643:"6b9a26f5",7698:"beb22e5d",7709:"a45faa55",7758:"0b9ad65b",7773:"240342b6",7803:"4d76c75b",7877:"2a2c61e7",7906:"795aa392",7930:"6924f01e",7972:"2a6a82d3",8045:"e204036c",8108:"15e2a19c",8112:"f88f3e24",8130:"cc174e15",8146:"047496b9",8158:"cfa83e34",8283:"0b0d66d2",8301:"a5671cc6",8401:"0f17bec8",8405:"12015b5c",8500:"c5f2ec17",8680:"df738802",8684:"d8ca081e",8822:"dfb31018",8886:"2a3134f2",8913:"b6f04e6e",8973:"ac57b1d6",8984:"ef715b7b",9023:"678fc887",9026:"6ca14753",9034:"fe974b18",9048:"15908900",9088:"b1d20ec4",9095:"32b19eb1",9262:"a7b41027",9366:"4fdeaedd",9383:"890494e4",9390:"f2ba5f8b",9401:"6bc20c68",9420:"88d0615d",9437:"5a49904a",9525:"a6567380",9640:"b1b54438",9647:"b2f2604d",9676:"9f747501",9677:"d65448fc",9692:"f6bbe8eb",9749:"940e50fa",9820:"c072ae0c",9858:"72bbc0ce",9978:"dee77249"}[a]+".js",r.miniCssF=a=>{},r.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(a){if("object"==typeof window)return window}}(),r.o=(a,e)=>Object.prototype.hasOwnProperty.call(a,e),c={},r.l=(a,e,f,d)=>{if(c[a])c[a].push(e);else{var b,t;if(void 0!==f)for(var o=document.getElementsByTagName("script"),n=0;n{b.onerror=b.onload=null,clearTimeout(l);var d=c[a];if(delete c[a],b.parentNode&&b.parentNode.removeChild(b),d&&d.forEach((a=>a(f))),e)return e(f)},l=setTimeout(u.bind(null,void 0,{type:"timeout",target:b}),12e4);b.onerror=u.bind(null,b.onerror),b.onload=u.bind(null,b.onload),t&&document.head.appendChild(b)}},r.r=a=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(a,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(a,"__esModule",{value:!0})},r.p="/",r.gca=function(a){return a={17896441:"8401",21614072:"2032",33776668:"1533",79263788:"4865",b05ccea0:"46","57bcddd6":"100",ac4b567d:"293","7f661f82":"411","4cccfac9":"457","34fbd09a":"468","7b1f0035":"485","61eca9d6":"492",f8092feb:"517","58972da3":"530",a373fd77:"553",acaf655c:"613","3c055f5e":"659","5aef2ce6":"700","3423820d":"741","56ebd09a":"777","0058b4c6":"849","71a2656f":"881","884bd1d2":"946",c141421f:"957",aa0b35eb:"1010",bbdc39ec:"1068","8919ea97":"1158",a7456010:"1235",e436f9fb:"1236","21a9d6ed":"1279",a8248417:"1410",d9e16301:"1416",c8131338:"1439","9d221b96":"1444",be77d225:"1463",abc9d724:"1599",b9f8aa82:"1610","6297ff83":"1652",a33b6a74:"1734","89b1f439":"1759","4dac5fec":"1822",f28f39ea:"1847",acecf23e:"1903","3eb0a99f":"1926","7a64ca81":"1932",a5a260f1:"1989","06d8773d":"1998",cd3b4295:"2057","1a4e3797":"2138",bf6aacca:"2212",c359af60:"2316",ae894706:"2365",ae565638:"2380",e44e3f47:"2385","6d752ef5":"2509",c4f5d8e4:"2634","9d4bdb35":"2708","9e4087bc":"2711","65dc7644":"2740","8a838ea0":"2883",d47ba782:"2938",a02168a2:"2968","8a061d83":"2996","3c653e3b":"3157","76c96f4d":"3212",ccc49370:"3249","9258f162":"3426","7b6b5c72":"3487","4c2546f9":"3526","6021085e":"3548","1772b9c1":"3699",eb0c92c1:"3716","70793eb2":"3730",a67edc69:"3838","5a5dcc21":"3967","3a27b2d9":"4215","00d3276d":"4235","5bb07cf5":"4261",e0f83a1d:"4341","8fb47bcc":"4478","937dc5a6":"4515",e6b9ef91:"4569",a2bed8f0:"4631",bd470307:"4638","812c592f":"4721","671939c9":"4728",c412bf64:"4765","491a3217":"4883",e9325e77:"4982","5573af76":"5041",fd7416f6:"5073",c8a5dae5:"5075",bf769997:"5118","0346afaa":"5277","420497a2":"5360","3c741b47":"5386","81cc3644":"5543","1d8647da":"5632","7efbfa7e":"5680",aba21aa0:"5742","25a5a20c":"6096","16fe8a4c":"6107",f22cd6c1:"6112",da41ed28:"6146","57dd985e":"6166","3a3b1bdb":"6227","38f5dda4":"6230","293e08e8":"6231",f5ff54f0:"6237","509dc7bf":"6241",aaff9110:"6408",b4a56aa4:"6499",fa38ac94:"6510",b388a56e:"6555","64f1f19c":"6629","58de4400":"6689",fa9ab54d:"6929","0c0efcaa":"6950",ca86781b:"7017",a7bd4aaa:"7098","5f403532":"7197","00e87d9a":"7207","0774da3f":"7211",a3e198d1:"7283","1df9637e":"7314","4b970726":"7318","7f18f0db":"7323","136023f9":"7331","1ed7bad6":"7343","04f8d6af":"7378","637f8365":"7417",ab17452f:"7419",bc20efef:"7436","814f3328":"7472",bab022f4:"7560","45d37095":"7586",b065408b:"7632",a6aa9e1f:"7643",cd83de9e:"7698","64cca8ef":"7709",f28ca027:"7758","184ad633":"7773",df12ff2a:"7803","3eac2097":"7877",f769b3fd:"7906","7dd0d394":"7930",acb2d06a:"7972","041e4035":"8045",aaa764ed:"8108",bc3f1a98:"8112",f81c1134:"8130",c15d9823:"8146","37d3b766":"8283","4f53e586":"8301","5acb8db5":"8405",e66621bc:"8500","3d9729af":"8680",c26add1d:"8684","3f2a1ecb":"8822","413f2abb":"8886","1dbe42a7":"8973","99c7964b":"8984","1fdfdeaa":"9023","5c708541":"9026",b7bf8e49:"9034",a94703ab:"9048","18328e9e":"9088",cf554d4e:"9095",d1458f14:"9262","0fe8a02a":"9366","223037ba":"9383",c222a988:"9390",a177ae00:"9401","0c78c462":"9420","8fdeae25":"9437",bf1307fc:"9525","9702a600":"9640","5e95c892":"9647",e305a15c:"9676","556d04db":"9677","1906a68b":"9692","8db808e7":"9749","4fb08289":"9820","36994c47":"9858","1c7a9c9f":"9978"}[a]||a,r.p+r.u(a)},(()=>{var a={5354:0,1869:0};r.f.j=(e,f)=>{var c=r.o(a,e)?a[e]:void 0;if(0!==c)if(c)f.push(c[2]);else if(/^(1869|5354)$/.test(e))a[e]=0;else{var d=new Promise(((f,d)=>c=a[e]=[f,d]));f.push(c[2]=d);var b=r.p+r.u(e),t=new Error;r.l(b,(f=>{if(r.o(a,e)&&(0!==(c=a[e])&&(a[e]=void 0),c)){var d=f&&("load"===f.type?"missing":f.type),b=f&&f.target&&f.target.src;t.message="Loading chunk "+e+" failed.\n("+d+": "+b+")",t.name="ChunkLoadError",t.type=d,t.request=b,c[1](t)}}),"chunk-"+e,e)}},r.O.j=e=>0===a[e];var e=(e,f)=>{var c,d,b=f[0],t=f[1],o=f[2],n=0;if(b.some((e=>0!==a[e]))){for(c in t)r.o(t,c)&&(r.m[c]=t[c]);if(o)var i=o(r)}for(e&&e(f);n

Perf regress
  • CONFIG_IMPACT
  • INEFFICIENT_KEYSET_ITERATOR
  • IPC_ON_UI_THREAD
  • +
  • LOCK_ON_UI_THREAD
  • PULSE_CONST_REFABLE
  • PULSE_READONLY_SHARED_PTR_PARAM
  • PULSE_UNNECESSARY_COPY
  • @@ -131,6 +132,7 @@

    Runtime ex
  • BAD_MAP_LATENT
  • BAD_RECORD
  • BAD_RECORD_LATENT
  • +
  • INFINITE_RECURSION
  • MISSING_REQUIRED_PROP
  • MUTUAL_RECURSION_CYCLE
  • NIL_INSERTION_INTO_COLLECTION
  • diff --git a/docs/next/all-checkers/index.html b/docs/next/all-checkers/index.html index bff36837883..5b006f9ba38 100644 --- a/docs/next/all-checkers/index.html +++ b/docs/next/all-checkers/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/next/all-issue-types/index.html b/docs/next/all-issue-types/index.html index 06d977286bb..45a0b29e510 100644 --- a/docs/next/all-issue-types/index.html +++ b/docs/next/all-issue-types/index.html @@ -13,7 +13,7 @@ - + @@ -408,6 +408,9 @@

    Example 3: T due to calling another T-costed function

    Since the analysis is inter-procedural, another example we can have T cost is if at least one of the callees has T cost.

    // Expected: constant, got T
    void call_top_cost_FP() {
    square_root_FP(1); // square_root_FP has Top cost
    }
    +

    INFINITE_RECURSION

    +

    Category: Runtime exception. Reported as "Infinite Recursion" by pulse.

    +

    A special case of MUTUAL_RECURSION_CYCLE where we detected that the recursive call is made with the exact same values, which guarantees an infinite recursion.

    INTEGER_OVERFLOW_L1

    Reported as "Integer Overflow L1" by bufferoverrun.

    This is reported when integer overflow occurred by integer operations such as addition, subtraction, @@ -498,6 +501,11 @@

    LOCK_ON_UI_THREAD

    +

    Category: Perf regression. Reported as "Lock on UI Thread" by starvation.

    +

    A method annoted as being on UIThread acquires a lock. This could be a potential performance issue

    +

    Example:

    +
    class Example {
    @UiThread
    void foo() {
    synchronized(this) {
    }
    }
    }

    MEMORY_LEAK_C

    Category: Resource leak. Reported as "Memory Leak" by pulse.

    Memory leak in C

    @@ -1365,6 +1373,6 @@

    Replace weakSelf with self:

      [self foo:^() {
    [self bar];
    }];

    Limitations: To keep this check simple and intra-procedural, we rely on names to find weakSelf: -we assume that any captured weak pointer whose name contains "self" is a weak reference to self.

    +we assume that any captured weak pointer whose name contains "self" is a weak reference to self.

    \ No newline at end of file diff --git a/docs/next/analyzing-apps-or-projects/index.html b/docs/next/analyzing-apps-or-projects/index.html index ba99d2413e0..821d7ac4dc9 100644 --- a/docs/next/analyzing-apps-or-projects/index.html +++ b/docs/next/analyzing-apps-or-projects/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/next/checker-annotation-reachability/index.html b/docs/next/checker-annotation-reachability/index.html index 81ae5456923..31664ab7138 100644 --- a/docs/next/checker-annotation-reachability/index.html +++ b/docs/next/checker-annotation-reachability/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/next/checker-biabduction/index.html b/docs/next/checker-biabduction/index.html index b8eb262fc08..a2799ca2bb0 100644 --- a/docs/next/checker-biabduction/index.html +++ b/docs/next/checker-biabduction/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/next/checker-bufferoverrun/index.html b/docs/next/checker-bufferoverrun/index.html index 6088d7ed518..c717b6baf6a 100644 --- a/docs/next/checker-bufferoverrun/index.html +++ b/docs/next/checker-bufferoverrun/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/next/checker-config-impact-analysis/index.html b/docs/next/checker-config-impact-analysis/index.html index 8a4ef34e47f..7fa47a3d2bc 100644 --- a/docs/next/checker-config-impact-analysis/index.html +++ b/docs/next/checker-config-impact-analysis/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/next/checker-cost/index.html b/docs/next/checker-cost/index.html index f2f598b7e41..6d62963b21a 100644 --- a/docs/next/checker-cost/index.html +++ b/docs/next/checker-cost/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/next/checker-fragment-retains-view/index.html b/docs/next/checker-fragment-retains-view/index.html index dc36769c108..ab20d806596 100644 --- a/docs/next/checker-fragment-retains-view/index.html +++ b/docs/next/checker-fragment-retains-view/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/next/checker-impurity/index.html b/docs/next/checker-impurity/index.html index f8a3a984e82..a3e840b4fa8 100644 --- a/docs/next/checker-impurity/index.html +++ b/docs/next/checker-impurity/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/next/checker-inefficient-keyset-iterator/index.html b/docs/next/checker-inefficient-keyset-iterator/index.html index 05dcf5456b8..c740c9d1dd8 100644 --- a/docs/next/checker-inefficient-keyset-iterator/index.html +++ b/docs/next/checker-inefficient-keyset-iterator/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/next/checker-lineage/index.html b/docs/next/checker-lineage/index.html index 4bfc66b08c9..65f41c6ba30 100644 --- a/docs/next/checker-lineage/index.html +++ b/docs/next/checker-lineage/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/next/checker-litho-required-props/index.html b/docs/next/checker-litho-required-props/index.html index 37faa42cc9e..62f1e46884d 100644 --- a/docs/next/checker-litho-required-props/index.html +++ b/docs/next/checker-litho-required-props/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/next/checker-liveness/index.html b/docs/next/checker-liveness/index.html index 31b40863337..fc3fde259fc 100644 --- a/docs/next/checker-liveness/index.html +++ b/docs/next/checker-liveness/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/next/checker-loop-hoisting/index.html b/docs/next/checker-loop-hoisting/index.html index 33d00e5103a..94df96d51b2 100644 --- a/docs/next/checker-loop-hoisting/index.html +++ b/docs/next/checker-loop-hoisting/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/next/checker-parameter-not-null-checked/index.html b/docs/next/checker-parameter-not-null-checked/index.html index d0709238b9e..c554d3164ac 100644 --- a/docs/next/checker-parameter-not-null-checked/index.html +++ b/docs/next/checker-parameter-not-null-checked/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/next/checker-pulse/index.html b/docs/next/checker-pulse/index.html index 726fef663d1..3091be6e1a8 100644 --- a/docs/next/checker-pulse/index.html +++ b/docs/next/checker-pulse/index.html @@ -13,7 +13,7 @@ - + @@ -66,6 +66,7 @@

    List of
  • CONSTANT_ADDRESS_DEREFERENCE
  • CONSTANT_ADDRESS_DEREFERENCE_LATENT
  • DATA_FLOW_TO_SINK
  • +
  • INFINITE_RECURSION
  • MEMORY_LEAK_C
  • MEMORY_LEAK_CPP
  • MUTUAL_RECURSION_CYCLE
  • diff --git a/docs/next/checker-purity/index.html b/docs/next/checker-purity/index.html index f51e1ffd561..c20e7672f16 100644 --- a/docs/next/checker-purity/index.html +++ b/docs/next/checker-purity/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/next/checker-racerd/index.html b/docs/next/checker-racerd/index.html index b5a5e0b8914..ff3e2763949 100644 --- a/docs/next/checker-racerd/index.html +++ b/docs/next/checker-racerd/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/next/checker-resource-leak-lab/index.html b/docs/next/checker-resource-leak-lab/index.html index cf1ba5854ae..b9596bb118c 100644 --- a/docs/next/checker-resource-leak-lab/index.html +++ b/docs/next/checker-resource-leak-lab/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/next/checker-scope-leakage/index.html b/docs/next/checker-scope-leakage/index.html index 3b6a2f8e1f9..81e3e1012e4 100644 --- a/docs/next/checker-scope-leakage/index.html +++ b/docs/next/checker-scope-leakage/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/next/checker-self-in-block/index.html b/docs/next/checker-self-in-block/index.html index e5266aab315..08466d7474e 100644 --- a/docs/next/checker-self-in-block/index.html +++ b/docs/next/checker-self-in-block/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/next/checker-sil-validation/index.html b/docs/next/checker-sil-validation/index.html index 3a116f6c5b4..51f284227b2 100644 --- a/docs/next/checker-sil-validation/index.html +++ b/docs/next/checker-sil-validation/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/next/checker-siof/index.html b/docs/next/checker-siof/index.html index c3e15043ffb..5eee73eeaa6 100644 --- a/docs/next/checker-siof/index.html +++ b/docs/next/checker-siof/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/next/checker-starvation/index.html b/docs/next/checker-starvation/index.html index 8b412c36565..f80587a2e58 100644 --- a/docs/next/checker-starvation/index.html +++ b/docs/next/checker-starvation/index.html @@ -13,7 +13,7 @@ - + @@ -42,6 +42,7 @@

    List of
  • DEADLOCK
  • IPC_ON_UI_THREAD
  • LOCKLESS_VIOLATION
  • +
  • LOCK_ON_UI_THREAD
  • REGEX_OP_ON_UI_THREAD
  • STARVATION
  • STRICT_MODE_VIOLATION
  • diff --git a/docs/next/checker-static-constructor-stall-checker/index.html b/docs/next/checker-static-constructor-stall-checker/index.html index fbf365fecc4..1450dc00d53 100644 --- a/docs/next/checker-static-constructor-stall-checker/index.html +++ b/docs/next/checker-static-constructor-stall-checker/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/next/checker-topl/index.html b/docs/next/checker-topl/index.html index 1b867e524ed..4c2bd8c1467 100644 --- a/docs/next/checker-topl/index.html +++ b/docs/next/checker-topl/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/next/getting-started/index.html b/docs/next/getting-started/index.html index b43347a6a26..95e53d4069d 100644 --- a/docs/next/getting-started/index.html +++ b/docs/next/getting-started/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/next/hello-world/index.html b/docs/next/hello-world/index.html index b05d708c2ed..534ac45f513 100644 --- a/docs/next/hello-world/index.html +++ b/docs/next/hello-world/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/next/infer-workflow/index.html b/docs/next/infer-workflow/index.html index 1ef8840a6ec..ffa529500ca 100644 --- a/docs/next/infer-workflow/index.html +++ b/docs/next/infer-workflow/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/next/internal-API/index.html b/docs/next/internal-API/index.html index 64e65c23641..ba889ca8dc6 100644 --- a/docs/next/internal-API/index.html +++ b/docs/next/internal-API/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/next/man-infer-analyze/index.html b/docs/next/man-infer-analyze/index.html index 8be7106b2ee..621428a7dcd 100644 --- a/docs/next/man-infer-analyze/index.html +++ b/docs/next/man-infer-analyze/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/next/man-infer-capture/index.html b/docs/next/man-infer-capture/index.html index 9e2a65b475d..ec7820c9afc 100644 --- a/docs/next/man-infer-capture/index.html +++ b/docs/next/man-infer-capture/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/next/man-infer-compile/index.html b/docs/next/man-infer-compile/index.html index faad2423dc0..61330ddb374 100644 --- a/docs/next/man-infer-compile/index.html +++ b/docs/next/man-infer-compile/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/next/man-infer-debug/index.html b/docs/next/man-infer-debug/index.html index ddc62d76b04..d28b0729a26 100644 --- a/docs/next/man-infer-debug/index.html +++ b/docs/next/man-infer-debug/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/next/man-infer-explore/index.html b/docs/next/man-infer-explore/index.html index ac375fdd671..b173d46dec8 100644 --- a/docs/next/man-infer-explore/index.html +++ b/docs/next/man-infer-explore/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/next/man-infer-help/index.html b/docs/next/man-infer-help/index.html index 661b73cd57d..33ea743d75a 100644 --- a/docs/next/man-infer-help/index.html +++ b/docs/next/man-infer-help/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/next/man-infer-report/index.html b/docs/next/man-infer-report/index.html index dc5f6b04de1..a81bbdaab0e 100644 --- a/docs/next/man-infer-report/index.html +++ b/docs/next/man-infer-report/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/next/man-infer-reportdiff/index.html b/docs/next/man-infer-reportdiff/index.html index 926a97ac6af..17b286ef146 100644 --- a/docs/next/man-infer-reportdiff/index.html +++ b/docs/next/man-infer-reportdiff/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/next/man-infer-run/index.html b/docs/next/man-infer-run/index.html index ec406933f87..f38c2ab326c 100644 --- a/docs/next/man-infer-run/index.html +++ b/docs/next/man-infer-run/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/next/man-infer/index.html b/docs/next/man-infer/index.html index 9167fa0918d..b832a89bd60 100644 --- a/docs/next/man-infer/index.html +++ b/docs/next/man-infer/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/next/man-pages/index.html b/docs/next/man-pages/index.html index 88f65ee4f47..972feccf1f1 100644 --- a/docs/next/man-pages/index.html +++ b/docs/next/man-pages/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/next/separation-logic-and-bi-abduction/index.html b/docs/next/separation-logic-and-bi-abduction/index.html index e6f5e6a3ce1..31507285745 100644 --- a/docs/next/separation-logic-and-bi-abduction/index.html +++ b/docs/next/separation-logic-and-bi-abduction/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/next/steps-for-ci/index.html b/docs/next/steps-for-ci/index.html index c3c89c7367e..2089f34cee1 100644 --- a/docs/next/steps-for-ci/index.html +++ b/docs/next/steps-for-ci/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/next/support/index.html b/docs/next/support/index.html index 80fd169d738..44ee3f96cd9 100644 --- a/docs/next/support/index.html +++ b/docs/next/support/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/next/suppressions/index.html b/docs/next/suppressions/index.html index 3a5a68b7c97..1445cfd3a57 100644 --- a/docs/next/suppressions/index.html +++ b/docs/next/suppressions/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/next/versions/index.html b/docs/next/versions/index.html index d8d84b6ab1a..320b3cb2b5b 100644 --- a/docs/next/versions/index.html +++ b/docs/next/versions/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/separation-logic-and-bi-abduction/index.html b/docs/separation-logic-and-bi-abduction/index.html index ff72ece0ea6..4fb46e32331 100644 --- a/docs/separation-logic-and-bi-abduction/index.html +++ b/docs/separation-logic-and-bi-abduction/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/steps-for-ci/index.html b/docs/steps-for-ci/index.html index fac000b1c27..dc7d3235af4 100644 --- a/docs/steps-for-ci/index.html +++ b/docs/steps-for-ci/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/support/index.html b/docs/support/index.html index afcba45cfa2..d709b3c4ce3 100644 --- a/docs/support/index.html +++ b/docs/support/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/versions/index.html b/docs/versions/index.html index 53601d64325..8bb34ceccf2 100644 --- a/docs/versions/index.html +++ b/docs/versions/index.html @@ -13,7 +13,7 @@ - + diff --git a/index.html b/index.html index a552ce44723..37e48d709c2 100644 --- a/index.html +++ b/index.html @@ -13,7 +13,7 @@ - + diff --git a/man/next/infer-analyze.1.html b/man/next/infer-analyze.1.html index 1a06c592fa5..3a40d3968de 100644 --- a/man/next/infer-analyze.1.html +++ b/man/next/infer-analyze.1.html @@ -1,4 +1,4 @@ - + @@ -44,7 +44,7 @@

    NAME

    -

    infer-analyze - +

    infer-analyze - analyze the files captured by infer

    SYNOPSIS @@ -52,7 +52,7 @@

    SYNOPSIS

    -

    infer +

    infer analyze [options]
    infer
    [options]

    @@ -61,7 +61,7 @@

    DESCRIPTION

    -

    Analyze the +

    Analyze the files captured in the project results directory and report.

    @@ -71,9 +71,9 @@

    OPTIONS -

    --annotation-reachability

    +

    --annotation-reachability

    -

    Activates: +

    Activates: annotation-reachability checker: Given pairs of source and sink annotations, e.g. ‘@A‘ and ‘@B‘, this checker will warn whenever some @@ -90,105 +90,104 @@

    OPTIONS --no-annotation-reachability)

    -

    --annotation-reachability-only

    +

    --annotation-reachability-only

    -

    Activates: Enable +

    Activates: Enable annotation-reachability and disable all other checkers (Conversely: --no-annotation-reachability-only)

    -

    --biabduction

    +

    --biabduction

    -

    Activates: biabduction +

    Activates: biabduction checker: This analysis deals with a range of issues, many linked to memory safety.

    -

    DEPRECATED: This has -been replaced by Pulse and will be removed
    +

    DEPRECATED: This has been +replaced by Pulse and will be removed
    in the next release.
    (Conversely: --no-biabduction)
    --biabduction-only

    -

    Activates: Enable +

    Activates: Enable biabduction and disable all other checkers (Conversely: --no-biabduction-only)

    -

    --biabduction-write-dotty

    +

    --biabduction-write-dotty

    -

    Activates: Produce dotty files +

    Activates: Produce dotty files for specs and retain cycles reports in infer-out/captured. (Conversely: --no-biabduction-write-dotty)

    -

    --bufferoverrun

    +

    --bufferoverrun

    -

    Activates: bufferoverrun +

    Activates: bufferoverrun checker: InferBO is a detector for out-of-bounds array accesses. (Conversely: --no-bufferoverrun)

    +

    --bufferoverrun-only

    -

    --bufferoverrun-only

    - -

    Activates: Enable +

    Activates: Enable bufferoverrun and disable all other checkers (Conversely: --no-bufferoverrun-only)

    -

    --changed-files-index +

    --changed-files-index file

    -

    Specify the file containing the +

    Specify the file containing the list of source files from which reactive analysis should start. Source files should be specified relative to project root or be absolute

    -

    --config-impact-analysis

    +

    --config-impact-analysis

    -

    Activates: +

    Activates: config-impact-analysis checker: [EXPERIMENTAL] Collects function that are called without config checks. (Conversely: --no-config-impact-analysis)

    -

    --config-impact-analysis-only

    +

    --config-impact-analysis-only

    -

    Activates: Enable +

    Activates: Enable config-impact-analysis and disable all other checkers (Conversely: --no-config-impact-analysis-only)

    -

    --continue-analysis

    +

    --continue-analysis

    -

    Activates: Continue the +

    Activates: Continue the analysis after more targets are captured by --continue. The other analysis options should be given the same before. Not compatible with --reanalyze and --incremental-analysis. (Conversely: --no-continue-analysis)

    -

    --cost

    +

    --cost

    -

    Activates: cost checker: +

    Activates: cost checker: Computes the asymptotic complexity of functions with respect to execution cost or other user defined resources. Can be used to detect changes in the complexity with ‘infer reportdiff‘. (Conversely: --no-cost)

    -

    --cost-only

    +

    --cost-only

    -

    Activates: Enable cost +

    Activates: Enable cost and disable all other checkers (Conversely: --no-cost-only)

    -

    --no-cost-suppress-func-ptr

    +

    --no-cost-suppress-func-ptr

    -

    Deactivates: Suppress printing +

    Deactivates: Suppress printing function pointers in cost reports (Conversely: --cost-suppress-func-ptr)

    -

    --debug,-g

    +

    --debug,-g

    -

    Activates: Debug mode (also +

    Activates: Debug mode (also sets --debug-level 2, --developer-mode, --print-buckets, --print-types, --reports-include-ml-loc, @@ -196,45 +195,45 @@

    OPTIONS --write-html) (Conversely: --no-debug | -G)

    -

    --debug-level +

    --debug-level level

    -

    Debug level (sets +

    Debug level (sets --bo-debug level, --debug-level-analysis level, --debug-level-capture level):

    -

    - 0: only basic debugging +

    - 0: only basic debugging enabled
    - 1: verbose debugging enabled
    - 2: very verbose debugging enabled
    --debug-level-analysis
    int

    -

    Debug level for the analysis. +

    Debug level for the analysis. See --debug-level for accepted values.

    -

    --debug-level-capture +

    --debug-level-capture int

    -

    Debug level for the capture. +

    Debug level for the capture. See --debug-level for accepted values.

    -

    --debug-level-report +

    --debug-level-report int

    -

    Debug level for the report. See +

    Debug level for the report. See --debug-level for accepted values.

    -

    --no-deduplicate

    +

    --no-deduplicate

    -

    Deactivates: Apply +

    Deactivates: Apply issue-specific deduplication during analysis and/or reporting. (Conversely: --deduplicate)

    -

    --no-default-checkers

    +

    --no-default-checkers

    -

    Deactivates: Default checkers: +

    Deactivates: Default checkers: --static-constructor-stall-checker, --fragment-retains-view, --inefficient-keyset-iterator, --liveness, @@ -244,9 +243,9 @@

    OPTIONS --default-checkers)

    -

    --detach-analysis-dependency

    +

    --detach-analysis-dependency

    -

    Activates: Detach analysis +

    Activates: Detach analysis dependencies of checkers during the analysis, so that each checker triggers themselves only when analyzing a callee. This can save unnecessary analyses on the situation that NOT @@ -255,89 +254,88 @@

    OPTIONS --no-detach-analysis-dependency)

    -

    --dict-missing-key-var-block-list +

    --dict-missing-key-var-block-list +string

    -

    Skip analyzing the variables in +

    Skip analyzing the variables in the dict-missing-key checker.

    - -

    --files-to-analyze-index +

    --files-to-analyze-index file

    -

    File containing a list of +

    File containing a list of source files where analysis should start from. When used, the set of files given to this argument must be a subset of that passed to --changed-files-index (which must be specified).

    -

    --no-fragment-retains-view

    +

    --no-fragment-retains-view

    -

    Deactivates: +

    Deactivates: fragment-retains-view checker: Detects when Android fragments are not explicitly nullified before becoming unreachable. (Conversely: --fragment-retains-view)

    -

    --fragment-retains-view-only

    +

    --fragment-retains-view-only

    -

    Activates: Enable +

    Activates: Enable fragment-retains-view and disable all other checkers (Conversely: --no-fragment-retains-view-only)

    -

    --help

    +

    --help

    -

    Show this manual

    +

    Show this manual

    -

    --help-format { auto -| groff | pager | plain }

    +

    --help-format { auto | +groff | pager | plain }

    -

    Show this help in the specified +

    Show this help in the specified format. auto sets the format to plain if the environment variable TERM is "dumb" or undefined, and to pager otherwise.

    -

    --help-full

    +

    --help-full

    -

    Show this manual with all +

    Show this manual with all internal options in the INTERNAL OPTIONS section

    -

    --impurity

    +

    --impurity

    -

    Activates: impurity +

    Activates: impurity checker: Detects functions with potential side-effects. Same as "purity", but implemented on top of Pulse.

    -

    ACTIVATES: pulse +

    ACTIVATES: pulse (Conversely: --no-impurity)
    --impurity-only

    -

    Activates: Enable +

    Activates: Enable impurity and disable all other checkers (Conversely: --no-impurity-only)

    -

    --impurity-report-immutable-modifications

    +

    --impurity-report-immutable-modifications

    -

    Activates: Report modifications +

    Activates: Report modifications to immutable fields in the Impurity checker (Conversely: --no-impurity-report-immutable-modifications)

    -

    --incremental-analysis

    +

    --incremental-analysis

    -

    Activates: Use incremental +

    Activates: Use incremental analysis for changed files. Not compatible with --reanalyze and --continue-analysis. Also sets --mark-unchanged-procs. (Conversely: --no-incremental-analysis)

    -

    --no-inefficient-keyset-iterator

    +

    --no-inefficient-keyset-iterator

    -

    Deactivates: +

    Deactivates: inefficient-keyset-iterator checker: Check for inefficient uses of iterators that iterate on keys then lookup their values, instead of iterating on key-value pairs @@ -345,157 +343,160 @@

    OPTIONS --inefficient-keyset-iterator)

    -

    --inefficient-keyset-iterator-only

    +

    --inefficient-keyset-iterator-only

    -

    Activates: Enable +

    Activates: Enable inefficient-keyset-iterator and disable all other checkers (Conversely: --no-inefficient-keyset-iterator-only)

    -

    --invalidate-only

    +

    --invalidate-only

    -

    Activates: Remove any summaries +

    Activates: Remove any summaries from the results database that transitively depend on a changed procedure, then exit without doing any actual analysis. (Conversely: --no-invalidate-only)

    -

    --jobs,-j +

    --jobs,-j int

    -

    Run the specified number of +

    Run the specified number of analysis jobs simultaneously. Defaults to the minimum value of the max_jobs argument and the number of CPUs.

    -

    --keep-going

    +

    --keep-going

    -

    Activates: Keep going when the +

    Activates: Keep going when the analysis or capture encounter a failure (Conversely: --no-keep-going)

    -

    --lineage

    +

    --lineage

    -

    Activates: lineage +

    Activates: lineage checker: Computes a dataflow graph (Conversely: --no-lineage)

    -

    --lineage-only

    +

    --lineage-only

    -

    Activates: Enable +

    Activates: Enable lineage and disable all other checkers (Conversely: --no-lineage-only)

    -

    --litho-required-props

    +

    --litho-required-props

    -

    Activates: +

    Activates: litho-required-props checker: Checks that all non-optional ‘@Prop‘s have been specified when constructing Litho components. (Conversely: --no-litho-required-props)

    -

    --litho-required-props-only

    +

    --litho-required-props-only

    -

    Activates: Enable +

    Activates: Enable litho-required-props and disable all other checkers (Conversely: --no-litho-required-props-only)

    -

    --no-liveness

    +

    --no-liveness

    -

    Deactivates: liveness +

    Deactivates: liveness checker: Detection of dead stores and unused variables. (Conversely: --liveness)

    -

    --liveness-ignored-constant +

    --liveness-ignored-constant +string

    -

    List of integer constants to be +

    List of integer constants to be ignored by liveness analysis

    -

    --liveness-only

    +

    --liveness-only

    -

    Activates: Enable +

    Activates: Enable liveness and disable all other checkers (Conversely: --no-liveness-only)

    -

    --log-missing-deps

    +

    --log-missing-deps

    -

    Activates: Log analysis +

    Activates: Log analysis dependencies that cannot be found. (Conversely: --no-log-missing-deps)

    -

    --loop-hoisting

    +

    --loop-hoisting

    -

    Activates: loop-hoisting +

    Activates: loop-hoisting checker: Detect opportunities to hoist function calls that are invariant outside of loop bodies for efficiency. (Conversely: --no-loop-hoisting)

    +

    --loop-hoisting-only

    -

    --loop-hoisting-only

    - -

    Activates: Enable +

    Activates: Enable loop-hoisting and disable all other checkers (Conversely: --no-loop-hoisting-only)

    -

    --max-jobs -int

    +

    --max-jobs int

    -

    Maximum number of analysis jobs +

    Maximum number of analysis jobs running simultaneously. Experiments show current best value is 40 jobs.

    -

    --memtrace-analysis-profiling

    +

    --memtrace-analysis-profiling

    -

    Activates: Generate OCaml +

    Activates: Generate OCaml analysis allocation traces in ‘infer-out/memtrace‘. (Conversely: --no-memtrace-analysis-profiling)

    - -

    --memtrace-sampling-rate +

    --memtrace-sampling-rate float

    -

    Sampling rate for Memtrace +

    Sampling rate for Memtrace allocation profiling. Default is 1e-6.

    -

    --modeled-expensive +

    --modeled-expensive json

    -

    Matcher or list of matchers for +

    Matcher or list of matchers for methods that should be considered expensive by the performance critical checker.

    -

    --never-returning-null +

    --multicore

    + +

    Activates: [EXPERIMENTAL] uses +multi-threading for analysis, currently partially or not +implemented. (Conversely: --no-multicore)

    + +

    --never-returning-null json

    -

    [Java only, all analyses] +

    [Java only, all analyses] Matcher or list of matchers for functions that never return null.

    -

    --noescaping-function-list +

    --noescaping-function-list +string

    -

    Useful for the check +

    Useful for the check CXX_REF_CAPTURED_IN_BLOCK. It declares a list of functions that take blocks as arguments that are no escaping but we cannot annotate them accordingly.

    -

    --objc-block-execution-macro +

    --objc-block-execution-macro string

    -

    Macro for executing Objective-C +

    Macro for executing Objective-C blocks safely.

    -

    --ondemand-recursion-restart-limit +

    --ondemand-recursion-restart-limit int

    -

    In order to make the analysis +

    In order to make the analysis of mutual recursion cycles deterministic in their output, the analysis of a cycle of mutually recursive functions may restart the analysis of the entire cycle from a @@ -507,146 +508,143 @@

    OPTIONS instead.

    -

    --no-parameter-not-null-checked

    +

    --no-parameter-not-null-checked

    -

    Deactivates: +

    Deactivates: parameter-not-null-checked checker: An Objective-C-specific analysis to detect when a block parameter is used before being checked for null first. (Conversely: --parameter-not-null-checked)

    -

    --parameter-not-null-checked-only

    +

    --parameter-not-null-checked-only

    -

    Activates: Enable +

    Activates: Enable parameter-not-null-checked and disable all other checkers (Conversely: --no-parameter-not-null-checked-only)

    -

    --print-active-checkers

    +

    --print-active-checkers

    -

    Activates: Print the active +

    Activates: Print the active checkers before starting the analysis (Conversely: --no-print-active-checkers)

    -

    --print-logs

    +

    --print-logs

    -

    Activates: Also log messages to +

    Activates: Also log messages to stdout and stderr (Conversely: --no-print-logs)

    - -

    --procs-to-analyze-index +

    --procs-to-analyze-index file

    -

    Specify the file containing an +

    Specify the file containing an Sexp representing a list of pairs of procedures and specializations to analyze. Only works with the restart scheduler.

    -

    --progress-bar-style -{ auto | plain | multiline }

    +

    --progress-bar-style { +auto | plain | multiline }

    -

    Style of the progress bar. +

    Style of the progress bar. auto selects multiline if connected to a tty, otherwise plain.

    - -

    --project-root,-C +

    --project-root,-C dir

    -

    Specify the root directory of +

    Specify the root directory of the project

    -

    --no-pulse

    +

    --no-pulse

    -

    Deactivates: pulse +

    Deactivates: pulse checker: General-purpose memory and value analysis engine. (Conversely: --pulse)

    -

    --pulse-only

    +

    --pulse-only

    -

    Activates: Enable pulse +

    Activates: Enable pulse and disable all other checkers (Conversely: --no-pulse-only)

    -

    --purity

    +

    --purity

    -

    Activates: purity +

    Activates: purity checker: Detects pure (side-effect-free) functions. A different implementation of "impurity". (Conversely: --no-purity)

    -

    --purity-only

    +

    --purity-only

    -

    Activates: Enable purity +

    Activates: Enable purity and disable all other checkers (Conversely: --no-purity-only)

    -

    --qualified-cpp-name-block-list +

    --qualified-cpp-name-block-list +string

    -

    Skip analyzing the procedures +

    Skip analyzing the procedures under the qualified cpp type name.

    -

    --quiet,-q

    +

    --quiet,-q

    -

    Activates: Do not print +

    Activates: Do not print anything on standard output. (Conversely: --no-quiet | -Q)

    -

    --no-racerd

    +

    --no-racerd

    -

    Deactivates: racerd +

    Deactivates: racerd checker: Thread safety analysis. (Conversely: --racerd)

    -

    --racerd-only

    +

    --racerd-only

    -

    Activates: Enable racerd +

    Activates: Enable racerd and disable all other checkers (Conversely: --no-racerd-only)

    +

    --reactive,-r

    -

    --reactive,-r

    - -

    Activates: Reactive mode: the +

    Activates: Reactive mode: the analysis starts from the files captured since the infer command started (Conversely: --no-reactive | -R)

    -

    --reactive-capture

    +

    --reactive-capture

    -

    Activates: Reactive capture: +

    Activates: Reactive capture: capture and analysis are interleaved. Currently this flag will only make the analysis generate a list of type names that were not found in the global tenv. The feature is only available for the Hack frontend for now. (Conversely: --no-reactive-capture)

    -

    --no-report

    +

    --no-report

    -

    Deactivates: Run the reporting +

    Deactivates: Run the reporting phase once the analysis has completed (Conversely: --report)

    -

    --report-force-relative-path

    +

    --report-force-relative-path

    -

    Activates: Force converting an +

    Activates: Force converting an absolute path to a relative path to the root directory (Conversely: --no-report-force-relative-path)

    -

    --results-dir,-o +

    --results-dir,-o dir

    -

    Write results and internal +

    Write results and internal files in the specified directory

    -

    --scope-leakage

    +

    --scope-leakage

    -

    Activates: scope-leakage +

    Activates: scope-leakage checker: The Java/Kotlin checker takes into account a set of "scope" annotations and a must-not-hold relation over the scopes. The checker raises an alarm if there exists @@ -654,161 +652,158 @@

    OPTIONS respective scopes SA and SB, such that must-not-hold(SA, SB). (Conversely: --no-scope-leakage)

    +

    --scope-leakage-only

    -

    --scope-leakage-only

    - -

    Activates: Enable +

    Activates: Enable scope-leakage and disable all other checkers (Conversely: --no-scope-leakage-only)

    -

    --no-self-in-block

    +

    --no-self-in-block

    -

    Deactivates: +

    Deactivates: self-in-block checker: An Objective-C-specific analysis to detect when a block captures ‘self‘. (Conversely: --self-in-block)

    +

    --self-in-block-only

    -

    --self-in-block-only

    - -

    Activates: Enable +

    Activates: Enable self-in-block and disable all other checkers (Conversely: --no-self-in-block-only)

    +

    --shrink-analysis-db

    -

    --shrink-analysis-db

    - -

    Activates: After analysis, +

    Activates: After analysis, delete analysis summaries (but not report summaries) and vacuum analysis database. (Conversely: --no-shrink-analysis-db)

    -

    --sil-validation

    +

    --sil-validation

    -

    Activates: +

    Activates: sil-validation checker: This checker validates that all SIL instructions in all procedure bodies conform to a (front-end specific) subset of SIL. (Conversely: --no-sil-validation)

    -

    --sil-validation-only

    +

    --sil-validation-only

    -

    Activates: Enable +

    Activates: Enable sil-validation and disable all other checkers (Conversely: --no-sil-validation-only)

    -

    --no-siof

    +

    --no-siof

    -

    Deactivates: siof +

    Deactivates: siof checker: Catches Static Initialization Order Fiascos in C++, that can lead to subtle, compiler-version-dependent errors. (Conversely: --siof)

    -

    --siof-only

    +

    --siof-only

    -

    Activates: Enable siof +

    Activates: Enable siof and disable all other checkers (Conversely: --no-siof-only)

    -

    --sqlite-cache-size +

    --sqlite-cache-size int

    -

    SQLite cache size in pages (if +

    SQLite cache size in pages (if positive) or kB (if negative), follows formal of corresponding SQLite PRAGMA.

    -

    --sqlite-lock-timeout +

    --sqlite-lock-timeout int

    -

    Timeout for SQLite results +

    Timeout for SQLite results database operations, in milliseconds.

    -

    --sqlite-max-blob-size +

    --sqlite-max-blob-size int

    -

    Maximum blob/string size for +

    Maximum blob/string size for data written in SQLite.

    -

    --sqlite-mmap-size +

    --sqlite-mmap-size int

    -

    Size of memory map for mmaped +

    Size of memory map for mmaped SQLite databases, zero value disables memory mapping.

    -

    --sqlite-page-size +

    --sqlite-page-size int

    -

    SQLite page size in bytes, must +

    SQLite page size in bytes, must be a power of two between 512 and 65536.

    -

    --no-starvation

    +

    --no-starvation

    -

    Deactivates: starvation +

    Deactivates: starvation checker: Detect various kinds of situations when no progress is being made because of concurrency errors. (Conversely: --starvation)

    -

    --starvation-only

    +

    --starvation-only

    -

    Activates: Enable +

    Activates: Enable starvation and disable all other checkers (Conversely: --no-starvation-only)

    -

    --no-static-constructor-stall-checker

    +

    --no-static-constructor-stall-checker

    -

    Deactivates: +

    Deactivates: static-constructor-stall-checker checker: Detect if dispatch_once is called from a static constructor. (Conversely: --static-constructor-stall-checker)

    -

    --static-constructor-stall-checker-only

    +

    --static-constructor-stall-checker-only

    -

    Activates: Enable +

    Activates: Enable static-constructor-stall-checker and disable all other checkers (Conversely: --no-static-constructor-stall-checker-only)

    -

    --timeout +

    --timeout float

    -

    Time after which any checker +

    Time after which any checker (except biabduction) should give up analysing the current function or method, in seconds

    -

    --top-longest-proc-duration-size +

    --top-longest-proc-duration-size int

    -

    Number of procedures for which +

    Number of procedures for which we track longest analysis duration info.

    -

    --topl

    +

    --topl

    -

    Activates: topl checker: +

    Activates: topl checker: Detect errors based on user-provided state machines describing temporal properties over multiple objects.

    -

    ACTIVATES: pulse +

    ACTIVATES: pulse (Conversely: --no-topl)
    --topl-only

    -

    Activates: Enable topl +

    Activates: Enable topl and disable all other checkers (Conversely: --no-topl-only)

    -

    --write-html

    +

    --write-html

    -

    Activates: Produce html debug +

    Activates: Produce html debug output for the analyses in infer-out/captured. This shows the abstract state of all analyses at each program point in the source code. Each captured source file has its own html page. This HTML file contains the source file, and at each line of

    -

    the file there are links to the +

    the file there are links to the nodes of the control flow graph
    of Infer's translation of that line of code into its intermediate
    @@ -819,7 +814,7 @@

    OPTIONS node. (Conversely: --no-write-html)
    --xcode-isysroot-suffix
    string

    -

    Specify the suffix of Xcode +

    Specify the suffix of Xcode isysroot directory, to avoid absolute paths in tests

    ANALYSIS SCHEDULER OPTIONS @@ -828,17 +823,17 @@

    ANALYSIS SCHEDULER OPTIONS -

    --analysis-schedule-file +

    --analysis-schedule-file path

    -

    The file where an analysis +

    The file where an analysis schedule is stored. The default is infer-out/analysis_dependency_graph

    -

    --replay-analysis-schedule

    +

    --replay-analysis-schedule

    -

    Activates: Replay the analysis +

    Activates: Replay the analysis schedule stored in --replay-analysis-schedule-file, which should analyze the procedures in the same order as the previous analysis. This should drastically limit @@ -848,9 +843,9 @@

    ANALYSIS SCHEDULER OPTIONS (Conversely: --no-replay-analysis-schedule)

    -

    --replay-ondemand-should-error

    +

    --replay-ondemand-should-error

    -

    Activates: [debug] Whether +

    Activates: [debug] Whether triggering the analysis of a procedure via ondemand should log an error when replaying an analysis schedule with --replay-analysis-schedule. Enable when replaying the @@ -858,13 +853,13 @@

    ANALYSIS SCHEDULER OPTIONS dependencies that were recorded are insufficient. (Conversely: --no-replay-ondemand-should-error)

    -

    --scheduler { file | +

    --scheduler { file | restart | callgraph }

    -

    Specify the scheduler used for +

    Specify the scheduler used for the analysis phase:

    -

    - file: schedules one job per +

    - file: schedules one job per file
    - callgraph: schedules one job per procedure, following the
    @@ -877,7 +872,7 @@

    ANALYSIS SCHEDULER OPTIONS thus performs generally better on high parallelism
    --store-analysis-schedule

    -

    Activates: Store the analysis +

    Activates: Store the analysis schedule for later replay, honoring --replay-analysis-schedule-file if present. This can be useful to store a schedule done with one version of infer @@ -894,58 +889,57 @@

    BUFFER OVERRUN OPTIONS -

    --no-bo-assume-void

    +

    --no-bo-assume-void

    -

    Deactivates: Assume void type +

    Deactivates: Assume void type as a type of record fields not in type environment. (Conversely: --bo-assume-void)

    -

    --no-bo-bottom-as-default

    +

    --no-bo-bottom-as-default

    -

    Deactivates: Use bottom as a +

    Deactivates: Use bottom as a default value instead of unknown. (Conversely: --bo-bottom-as-default)

    -

    --bo-context-sensitive-allocsites

    +

    --bo-context-sensitive-allocsites

    -

    Activates: Assume that +

    Activates: Assume that different calls to the same function creating an allocsite results in different allocsites imported to the caller. (Conversely: --no-bo-context-sensitive-allocsites)

    -

    --bo-debug -int

    +

    --bo-debug int

    -

    Debug level for buffer-overrun +

    Debug level for buffer-overrun checker (0-4)

    -

    --bo-exit-frontend-gener-vars

    +

    --bo-exit-frontend-gener-vars

    -

    Activates: Put frontend +

    Activates: Put frontend generated variables out of scope when they are listed in exit scope instruction. (Conversely: --no-bo-exit-frontend-gener-vars)

    -

    --bo-field-depth-limit +

    --bo-field-depth-limit int

    -

    Limit of field depth of +

    Limit of field depth of abstract location in buffer-overrun checker

    -

    --bo-max-cfg-size +

    --bo-max-cfg-size int

    -

    Larger CFGs than the max size +

    Larger CFGs than the max size are skipped in buffer overrun analysis.

    -

    --bo-sound-unknown-sets-join

    +

    --bo-sound-unknown-sets-join

    -

    Activates: Join with an unknown +

    Activates: Join with an unknown set always result in an unknown set. When disabled, unknown set behaves as bot. (Conversely: --no-bo-sound-unknown-sets-join)

    @@ -956,57 +950,57 @@

    CLANG OPTIONS -

    --biabduction-unsafe-malloc

    +

    --biabduction-unsafe-malloc

    -

    Activates: Assume that +

    Activates: Assume that malloc(3) never returns null. (Conversely: --no-biabduction-unsafe-malloc)

    -

    --clang-compound-literal-init-limit +

    --clang-compound-literal-init-limit int

    -

    Limit after which +

    Limit after which initialization of compound types (structs and arrays) is not done element by element but using a builtin function that each analysis has to model.

    -

    --cxx-scope-guards +

    --cxx-scope-guards json

    -

    Specify scope guard classes +

    Specify scope guard classes that can be read only by destructors without being reported as dead stores.

    -

    --dynamic-dispatch-json-file-path +

    --dynamic-dispatch-json-file-path path

    -

    Dynamic dispatch file path to +

    Dynamic dispatch file path to get the JSON used for method name substitution

    -

    --inline-func-pointer-for-testing +

    --inline-func-pointer-for-testing string

    -

    Enables substituting global +

    Enables substituting global function pointers used for testing with the real function calls in the clang frontend. Pass the prefix used to build the global function pointers used for testing.

    -

    --liveness-block-list-var-regex +

    --liveness-block-list-var-regex string

    -

    Specify a regular expression +

    Specify a regular expression for variable names that are ignored when reporting dead stores.

    -

    --liveness-dangerous-classes +

    --liveness-dangerous-classes json

    -

    Specify classes where the +

    Specify classes where the destructor should be ignored when computing liveness. In other words, assignement to variables of these types (or common wrappers around these types such as @@ -1014,26 +1008,26 @@

    CLANG OPTIONS when the variables are not read explicitly by the program.

    -

    --lock-model +

    --lock-model json

    -

    Specify custom lock models for +

    Specify custom lock models for starvation analysis.

    -

    Example for pthreads (already +

    Example for pthreads (already included in infer):
    [{"lock":["pthread_mutex_lock"],"unlock":["pthread_mutex_unlock"]}]
    --pulse-model-unreachable
    +string

    -

    Methods to be modeled as +

    Methods to be modeled as unreachable.

    -

    --pulse-unsafe-malloc

    +

    --pulse-unsafe-malloc

    -

    Activates: Assume that +

    Activates: Assume that malloc(3) never returns null. (Conversely: --no-pulse-unsafe-malloc)

    @@ -1043,16 +1037,16 @@

    ERLANG OPTIONS -

    --erlang-list-unfold-depth +

    --erlang-list-unfold-depth int

    -

    Unfold Erlang lists up to depth +

    Unfold Erlang lists up to depth int

    -

    --no-erlang-reliability

    +

    --no-erlang-reliability

    -

    Deactivates: Analyze crashing +

    Deactivates: Analyze crashing executions. This flag affects both capture and analysis. At capture time, it encodes Erlang specs; at (Pulse) analysis time, it models Erlang exceptions (builtin or OTP ones). @@ -1064,39 +1058,39 @@

    JAVA OPTIONS -

    --no-annotation-reachability-apply-superclass-annotations

    +

    --no-annotation-reachability-apply-superclass-annotations

    -

    Deactivates: Applies +

    Deactivates: Applies annotations from superclasses and interfaces also on methods that are not overridden from the superclass or interface. (Conversely: --annotation-reachability-apply-superclass-annotations)

    -

    --annotation-reachability-check-loops

    +

    --annotation-reachability-check-loops

    -

    Activates: Highlights callsites +

    Activates: Highlights callsites in the trace that are nested in some loop. (Conversely: --no-annotation-reachability-check-loops)

    -

    --annotation-reachability-custom-models +

    --annotation-reachability-custom-models json

    -

    Specify a map from annotations +

    Specify a map from annotations to lists of regexps to treat matching methods as if they had the annotation.

    -

    Example format: +

    Example format: {"Annotation": ["com\\.Myclass\\.foo.*"]}
    --annotation-reachability-custom-pairs
    json

    -

    Specify custom sources/sinks, +

    Specify custom sources/sinks, and optionally sanitizers for the annotation reachability checker

    -

    Example format: for custom +

    Example format: for custom annotations
    com.my.annotation.{Source1,Source2,Sink1,Sanitizer1}
    { "sources" : ["Source1", @@ -1105,16 +1099,16 @@

    JAVA OPTIONS "sanitizers": ["Sanitizer1"] }
    --annotation-reachability-expensive

    -

    Activates: check if methods +

    Activates: check if methods annotated with @PerformanceCritical can call expensive methods (annotated @Expensive or modeled, with annotation reachability checker) (Conversely: --no-annotation-reachability-expensive)

    -

    --no-annotation-reachability-minimize-sinks

    +

    --no-annotation-reachability-minimize-sinks

    -

    Deactivates: do not report +

    Deactivates: do not report paths where a prefix is also a source to sink path. For example if there is a source() -> sink1() -> sink2() path then only source() -> sink1() will be reported. @@ -1122,43 +1116,42 @@

    JAVA OPTIONS --annotation-reachability-minimize-sinks)

    -

    --annotation-reachability-minimize-sources

    +

    --annotation-reachability-minimize-sources

    -

    Activates: do not report paths +

    Activates: do not report paths where a suffix is also a source to sink path. For example if there is a source1() -> source2() -> sink() path then only source2() -> sink() will be reported. (Conversely: --no-annotation-reachability-minimize-sources)

    -

    --annotation-reachability-no-allocation

    +

    --annotation-reachability-no-allocation

    -

    Activates: check if methods +

    Activates: check if methods annotated with @NoAllocation can allocate (with annotation reachability checker) (Conversely: --no-annotation-reachability-no-allocation)

    -

    --annotation-reachability-report-source-and-sink

    +

    --annotation-reachability-report-source-and-sink

    -

    Activates: Reports methods that +

    Activates: Reports methods that are marked as both a source and a sink at the same time. (Conversely: --no-annotation-reachability-report-source-and-sink)

    - -

    --external-java-packages +

    --external-java-packages +prefix

    -

    Specify a list of Java package +

    Specify a list of Java package prefixes for external Java packages. If set, the analysis will not report non-actionable warnings on those packages.

    -

    --java-version +

    --java-version int

    -

    The version of Java being used. +

    The version of Java being used. Set it to your Java version if mvn is failing.

    LINEAGE OPTIONS @@ -1167,93 +1160,93 @@

    LINEAGE OPTIONS -

    --no-lineage-dedup

    +

    --no-lineage-dedup

    -

    Deactivates: In JSON output, +

    Deactivates: In JSON output, attempt to print each entity at most once. This is the default. The only reason you may want to turn this off is to make hash collisions more visible; that is, cases in which distinct entities get assigned the same ID. (Conversely: --lineage-dedup)

    -

    --lineage-field-depth +

    --lineage-field-depth int

    -

    [EXPERIMENTAL] Maximal field +

    [EXPERIMENTAL] Maximal field depth sensitivity for lineage analysis. 0 will make the analysis field insensitive.

    -

    --lineage-field-max-cfg-size +

    --lineage-field-max-cfg-size int

    -

    If set, field sensitivity is +

    If set, field sensitivity is disabled on larger CFGs.

    -

    --lineage-field-width +

    --lineage-field-width int

    -

    [EXPERIMENTAL] Maximal width of +

    [EXPERIMENTAL] Maximal width of structures for field sensitive lineage analysis. Structure that have a higher number of fields will be smashed into a single element. 0 will make the analysis field insensitive.

    -

    --lineage-include-builtins

    +

    --lineage-include-builtins

    -

    Activates: Include call/return +

    Activates: Include call/return edges to/from procedures that model primitive Erlang operations, such as constructing a list. (Conversely: --no-lineage-include-builtins)

    -

    --lineage-json-report

    +

    --lineage-json-report

    -

    Activates: Enable lineage +

    Activates: Enable lineage report in JSON format. (Conversely: --no-lineage-json-report)

    -

    --lineage-keep-temporaries

    +

    --lineage-keep-temporaries

    -

    Activates: Normally, lineage +

    Activates: Normally, lineage summaries do not mention temporary variables introduced while compiling the high-level code to Infer's IR (intermediate representation). If this option is enabled, then the lineage graph produced corresponds to Infer's IR. (Conversely: --no-lineage-keep-temporaries)

    -

    --lineage-max-cfg-size +

    --lineage-max-cfg-size int

    -

    If set, larger CFGs are +

    If set, larger CFGs are skipped.

    -

    --no-lineage-prevent-cycles

    +

    --no-lineage-prevent-cycles

    -

    Deactivates: [EXPERIMENTAL] If +

    Deactivates: [EXPERIMENTAL] If given, Lineage will not stop traversing the fields of a variable when it notices recursive types (that is, a sub-field having the same type as one of its "ancestors"). (Conversely: --lineage-prevent-cycles)

    -

    --lineage-seed +

    --lineage-seed int

    -

    Set the random seed used for +

    Set the random seed used for hashing. (Various entities that get reported need unique identifiers. To generate these unique identifiers, in a distributed way without communication, we use hashing. If you are unlucky and get collisions, you can try a different seed.

    -

    --lineage-variant-width +

    --lineage-variant-width int

    -

    Maximal width of variant types +

    Maximal width of variant types for lineage analysis. A variant type is the type of a variable whose value is within a statically known atom set. The width of the type is the cardinal of that atom set.

    @@ -1264,40 +1257,40 @@

    PULSE CHECKER OPTIONS -

    --log-pulse-coverage

    +

    --log-pulse-coverage

    -

    Activates: Log precisely where +

    Activates: Log precisely where coverage stops, at the end of file stats/stats.txt. (Conversely: --no-log-pulse-coverage)

    -

    --log-pulse-disjunct-increase-after-model-call

    +

    --log-pulse-disjunct-increase-after-model-call

    -

    Activates: Log which model did +

    Activates: Log which model did increase the current number of Pulse disjuncts. (Conversely: --no-log-pulse-disjunct-increase-after-model-call)

    -

    --pulse-cut-to-one-path-procedures-pattern +

    --pulse-cut-to-one-path-procedures-pattern string

    -

    Regex of methods for which +

    Regex of methods for which pulse will only explore one path. Can be used on pathologically large procedures to prevent too-big states from being produced.

    -

    --pulse-inline-global-init-func-pointer

    +

    --pulse-inline-global-init-func-pointer

    -

    Activates: Inline the +

    Activates: Inline the initializer of global variables that are of type function pointer in Pulse. (Conversely: --no-pulse-inline-global-init-func-pointer)

    -

    --pulse-log-summary-count

    +

    --pulse-log-summary-count

    -

    Activates: Log the number of +

    Activates: Log the number of summaries (grouped by summary kind) for each analyzed procedure in Pulse. Results are put in JSON files under a 'pulse' subdirectory, one corresponding to each analysis @@ -1305,57 +1298,57 @@

    PULSE CHECKER OPTIONS be needed. (Conversely: --no-pulse-log-summary-count)

    -

    --pulse-max-cfg-size +

    --pulse-max-cfg-size int

    -

    Larger CFGs than the max size +

    Larger CFGs than the max size are skipped in Pulse.

    -

    --pulse-max-disjuncts +

    --pulse-max-disjuncts int

    -

    Stop exploring new paths after +

    Stop exploring new paths after int disjunctions in the domain

    -

    --pulse-max-heap +

    --pulse-max-heap int

    -

    Give up analysing a procedure +

    Give up analysing a procedure if the number of words in the heap exceeds this limit. Intended use: avoid OutOfMemory crashes.

    -

    --pulse-model-abort +

    --pulse-model-abort +string

    -

    Methods that should be modelled +

    Methods that should be modelled as abort in Pulse

    -

    --pulse-model-alloc-pattern +

    --pulse-model-alloc-pattern string

    -

    Regex of methods that should be +

    Regex of methods that should be modelled as allocs in Pulse

    -

    --pulse-model-cheap-copy-type +

    --pulse-model-cheap-copy-type regex

    -

    Regex of methods that should be +

    Regex of methods that should be cheap to copy in Pulse

    -

    --pulse-model-cheap-copy-type-list +

    --pulse-model-cheap-copy-type-list +regex

    -

    Regex of methods that should be +

    Regex of methods that should be cheap to copy in Pulse

    -

    --pulse-model-free-pattern +

    --pulse-model-free-pattern string

    -

    Regex of methods that should be +

    Regex of methods that should be modelled as wrappers to free(3) in Pulse. The pointer to be freed should be the first argument of the function. This should only be needed if the code of the wrapper is not @@ -1364,105 +1357,105 @@

    PULSE CHECKER OPTIONS pointers).

    -

    --pulse-model-malloc-pattern +

    --pulse-model-malloc-pattern string

    -

    Regex of methods that should be +

    Regex of methods that should be modelled as wrappers to malloc(3) in Pulse. The size to allocate should be the first argument of the function. See --pulse-model-free-pattern for more information.

    -

    --pulse-model-realloc-pattern +

    --pulse-model-realloc-pattern string

    -

    Regex of methods that should be +

    Regex of methods that should be modelled as wrappers to realloc(3) in Pulse. The pointer to be reallocated should be the first argument of the function and the new size the second argument. See --pulse-model-free-pattern for more information.

    -

    --pulse-model-release-pattern +

    --pulse-model-release-pattern string

    -

    Regex of methods that should be +

    Regex of methods that should be modelled as release in Pulse

    -

    --pulse-model-return-first-arg +

    --pulse-model-return-first-arg string

    -

    Regex of methods that should be +

    Regex of methods that should be modelled as returning the first argument in Pulse in terms of the source language semantics. Languages supported: Java, C, Objective-C

    -

    --pulse-model-return-nonnull +

    --pulse-model-return-nonnull string

    -

    Regex of methods that should be +

    Regex of methods that should be modelled as returning non-null in Pulse

    -

    --pulse-model-return-nonnull-list +

    --pulse-model-return-nonnull-list +string

    -

    Regex of methods that should be +

    Regex of methods that should be modelled as returning non-null in Pulse

    -

    --pulse-model-return-this +

    --pulse-model-return-this string

    -

    Regex of methods that should be +

    Regex of methods that should be modelled as returning the ‘this‘ or ‘self‘ argument of an instance method in Pulse. Languages supported: Java, Objective-C

    -

    --pulse-model-returns-copy-pattern +

    --pulse-model-returns-copy-pattern string

    -

    Regex of methods that should be +

    Regex of methods that should be modelled as creating copies in Pulse

    -

    --pulse-model-skip-pattern +

    --pulse-model-skip-pattern string

    -

    Regex of methods that should be +

    Regex of methods that should be modelled as "skip" in Pulse

    -

    --pulse-model-skip-pattern-list +

    --pulse-model-skip-pattern-list +string

    -

    Regex of methods that should be +

    Regex of methods that should be modelled as "skip" in Pulse

    -

    --pulse-model-transfer-ownership +

    --pulse-model-transfer-ownership +string

    -

    Methods that should be modelled +

    Methods that should be modelled as transfering memory ownership in Pulse. Accepted formats are method or namespace::method

    -

    --pulse-model-unknown-pure +

    --pulse-model-unknown-pure +string

    -

    Regex of methods that should be +

    Regex of methods that should be modelled as unknown pure in Pulse

    -

    --pulse-models-for-erlang +

    --pulse-models-for-erlang +path

    -

    Provide custom models for +

    Provide custom models for Erlang in JSON files or SQLite3. Files must end with ‘.json‘ or ‘.db‘ respectively. If a path to a directory is given then the subdirectories will be @@ -1470,7 +1463,7 @@

    PULSE CHECKER OPTIONS format is preferable when providing a large number of models because they will be internally indexed by mfa.

    -

    The format for JSON is +

    The format for JSON is [SelectorBehavior, ...] where
    SelectorBehavior := {"selector": Selector, "behavior": Behavior}
    @@ -1511,58 +1504,58 @@

    PULSE CHECKER OPTIONS (see above)
    --no-pulse-nullsafe-report-npe

    -

    Deactivates: Report null +

    Deactivates: Report null dereference issues on files marked @Nullsafe. (Conversely: --pulse-nullsafe-report-npe)

    -

    --pulse-nullsafe-report-npe-as-separate-issue

    +

    --pulse-nullsafe-report-npe-as-separate-issue

    -

    Activates: Report null +

    Activates: Report null dereference issues on files marked @Nullsafe as a separate NULLPTR_DEREFERENCE_IN_NULLSAFE_CLASS issue type. (Conversely: --no-pulse-nullsafe-report-npe-as-separate-issue)

    -

    --pulse-over-approximate-reasoning

    +

    --pulse-over-approximate-reasoning

    -

    Activates: [EXPERIMENTAL] add +

    Activates: [EXPERIMENTAL] add over-approximate reasoning on top of the under-approximate, disjunctive reasoning of Pulse. (Conversely: --no-pulse-over-approximate-reasoning)

    -

    --pulse-recency-limit +

    --pulse-recency-limit int

    -

    Maximum number of array +

    Maximum number of array elements and structure fields to keep track of for a given address.

    -

    --pulse-skip-procedures +

    --pulse-skip-procedures regex

    -

    Regex of procedures that should +

    Regex of procedures that should not be analyzed by Pulse.

    -

    --pulse-specialization-iteration-limit +

    --pulse-specialization-iteration-limit int

    -

    Maximum number of iterative +

    Maximum number of iterative summary specialization at each call site.

    -

    --pulse-specialization-limit +

    --pulse-specialization-limit int

    -

    Maximum number of summary +

    Maximum number of summary specialization by procedure.

    -

    --pulse-taint-config +

    --pulse-taint-config +path

    -

    Path to a taint analysis +

    Path to a taint analysis configuration file or a directory containing such files. This file can define --pulse-taint-sources, --pulse-taint-sanitizers, @@ -1570,7 +1563,7 @@

    PULSE CHECKER OPTIONS --pulse-taint-sinks, --pulse-taint-policies, and --pulse-taint-data-flow-kinds.

    -

    If a path to a directory is +

    If a path to a directory is given then the configuration files
    must have the ‘.json‘ extension. Any other file will be ignored.
    @@ -1579,38 +1572,37 @@

    PULSE CHECKER OPTIONS convention.
    --pulse-taint-data-flow-kinds
    json

    -

    Specify which taint kinds +

    Specify which taint kinds should be used for data flow reporting only. If a source has such a kind, only data flows to sinks which originate at the source will be reported. If a sink has such a kind, only sensitive data flows to the sink will be reported.

    -

    --no-pulse-taint-follow-field-accesses

    +

    --no-pulse-taint-follow-field-accesses

    -

    Deactivates: Specify if taint +

    Deactivates: Specify if taint analysis should follow field accesses when propagating taints. (Conversely: --pulse-taint-follow-field-accesses)

    -

    --pulse-taint-opaque-files +

    --pulse-taint-opaque-files +path

    -

    Specify files that should be +

    Specify files that should be treated as opaque for taint analysis to make sure that procedure's belonging to these files are always free of any potential taint flows.

    -

    --pulse-taint-policies +

    --pulse-taint-policies json

    -

    A description of which taint +

    A description of which taint flows should be reported, following this JSON format:

    -

    { -"short_description": "<a short description -of the issue>",
    +

    { "short_description": +"<a short description of the issue>",
    "taint_flows": [{ "source_kinds": [<kinds>],
    "sink_kinds": [<kinds>],
    @@ -1636,48 +1628,47 @@

    PULSE CHECKER OPTIONS }
    --pulse-taint-propagators
    json

    -

    Quick way to specify simple +

    Quick way to specify simple propagators as a JSON objects. See --pulse-taint-sources for the fields format documentation.

    - -

    --pulse-taint-sanitizers +

    --pulse-taint-sanitizers json

    -

    Quick way to specify simple +

    Quick way to specify simple sanitizers as a JSON objects. See --pulse-taint-sources for the fields format documentation.

    -

    --pulse-taint-short-traces

    +

    --pulse-taint-short-traces

    -

    Activates: Cut off taint traces +

    Activates: Cut off taint traces as soon as a tainted value flows into a sink. This matters when the sink itself calls other sinks of the same kind and as long as the value flows from call to call, without this flag the trace would include the whole chain of calls. (Conversely: --no-pulse-taint-short-traces)

    -

    --pulse-taint-sinks +

    --pulse-taint-sinks json

    -

    Quick way to specify simple +

    Quick way to specify simple sinks as a JSON objects. See --pulse-taint-sources for the fields format documentation.

    -

    --pulse-taint-skip-sources

    +

    --pulse-taint-skip-sources

    -

    Activates: Skip the analysis of +

    Activates: Skip the analysis of methods declared as sources in the taint. (Conversely: --no-pulse-taint-skip-sources)

    -

    --pulse-taint-sources +

    --pulse-taint-sources json

    -

    Together with +

    Together with --pulse-taint-sanitizers, --pulse-taint-sinks, --pulse-taint-policies, and --pulse-taint-data-flow-kinds, specify taint @@ -1686,8 +1677,8 @@

    PULSE CHECKER OPTIONS one of the following combinations of fields to identify relevant procedures:

    -

    - "field_regex": -match a field name using an OCaml regex
    +

    - "field_regex": match +a field name using an OCaml regex
    - "procedure": match a substring of the procedure name
    - "procedure_regex": as above, but match using an @@ -1794,50 +1785,37 @@

    PULSE CHECKER OPTIONS source shouldn't be flagged.
    --pulse-widen-threshold
    int

    -

    Stop exploring new paths after +

    Stop exploring new paths after int loop iterations

    -

    --python-globals { -own-by-closures | own-by-module }

    - -

    Specify the strategy to wire -globals dictionnaire into each function

    - -

    - own-by-closures: each closure -captured the global
    -dictionary
    -- own-by-module: each function is given the global -dictionary as
    -argument (not referenced in the heap to avoid aliases)

    -

    RACERD CHECKER OPTIONS

    -

    --racerd-always-report-java

    +

    --racerd-always-report-java

    -

    Activates: Every Java class +

    Activates: Every Java class analysed is treated as if it were annotated as @ThreadSafe. (Conversely: --no-racerd-always-report-java)

    -

    --racerd-guardedby

    +

    --racerd-guardedby

    -

    Activates: Check @GuardedBy +

    Activates: Check @GuardedBy annotations with RacerD (Conversely: --no-racerd-guardedby)

    -

    --racerd-ignore-classes +

    --racerd-ignore-classes +string

    -

    Any method in a class specified +

    Any method in a class specified here will be ignored by RacerD.

    -

    --threadsafe-aliases +

    --threadsafe-aliases json

    -

    Specify custom annotations that +

    Specify custom annotations that should be considered aliases of @ThreadSafe

    SIOF CHECKER OPTIONS @@ -1846,19 +1824,19 @@

    SIOF CHECKER OPTIONS -

    --siof-check-iostreams

    +

    --siof-check-iostreams

    -

    Activates: Do not assume that +

    Activates: Do not assume that iostreams (cout, cerr, ...) are always initialized. The default is to assume they are always initialized to avoid false positives. However, if your program compiles against a recent libstdc++ then it is safe to turn this option on. (Conversely: --no-siof-check-iostreams)

    -

    --siof-safe-methods +

    --siof-safe-methods +string

    -

    Methods that are SIOF-safe; +

    Methods that are SIOF-safe; "foo::bar" will match "foo::bar()", "foo<int>::bar()", etc. (can be specified multiple times)

    @@ -1869,10 +1847,10 @@

    ENVIRONMENT -

    INFER_ARGS, +

    INFER_ARGS, INFERCONFIG, INFER_STRICT_MODE

    -

    See the ENVIRONMENT section in +

    See the ENVIRONMENT section in the manual of infer(1).

    FILES @@ -1881,9 +1859,9 @@

    FILES -

    .inferconfig

    +

    .inferconfig

    -

    See the FILES section in the +

    See the FILES section in the manual of infer(1).

    SEE ALSO @@ -1892,7 +1870,7 @@

    SEE ALSO -

    infer-report(1), +

    infer-report(1), infer-run(1)


    diff --git a/man/next/infer-capture.1.html b/man/next/infer-capture.1.html index 978295dd9f3..5ec0f02004f 100644 --- a/man/next/infer-capture.1.html +++ b/man/next/infer-capture.1.html @@ -1,4 +1,4 @@ - + @@ -39,7 +39,7 @@

    NAME

    -

    infer-capture - +

    infer-capture - capture source files for later analysis

    SYNOPSIS @@ -47,9 +47,9 @@

    SYNOPSIS

    -

    infer -capture --buck-java [options] -- buck -...
    +

    infer capture +--buck-java [options] -- buck ... +
    infer capture --buck-clang
    [options] -- buck ...
    infer capture --buck-compilation-database
    [no-]deps @@ -80,7 +80,7 @@

    DESCRIPTION

    -

    Capture the +

    Capture the build command, compilation database, or cfg/tenv json files specified on the command line: infer intercepts calls to the compiler to read source files, translate them into infer's @@ -93,29 +93,29 @@

    OPTIONS -

    --capture-block-list +

    --capture-block-list json

    -

    Matcher or list of matchers for +

    Matcher or list of matchers for names of files that should not be captured, hence not analyzed either. Clang, Java, and Hack only.

    -

    --cfg-json +

    --cfg-json file

    -

    Path to CFG json file

    +

    Path to CFG json file

    -

    --continue

    +

    --continue

    -

    Activates: Continue the capture +

    Activates: Continue the capture for the reactive analysis, increasing the changed files/procedures. (If a procedure was changed beforehand, keep the changed marking.) (Conversely: --no-continue)

    -

    --debug,-g

    +

    --debug,-g

    -

    Activates: Debug mode (also +

    Activates: Debug mode (also sets --debug-level 2, --developer-mode, --print-buckets, --print-types, --reports-include-ml-loc, @@ -123,47 +123,47 @@

    OPTIONS --write-html) (Conversely: --no-debug | -G)

    -

    --debug-level +

    --debug-level level

    -

    Debug level (sets +

    Debug level (sets --bo-debug level, --debug-level-analysis level, --debug-level-capture level):

    -

    - 0: only basic debugging +

    - 0: only basic debugging enabled
    - 1: verbose debugging enabled
    - 2: very verbose debugging enabled
    --debug-level-analysis
    int

    -

    Debug level for the analysis. +

    Debug level for the analysis. See --debug-level for accepted values.

    -

    --debug-level-capture +

    --debug-level-capture int

    -

    Debug level for the capture. +

    Debug level for the capture. See --debug-level for accepted values.

    -

    --debug-level-report +

    --debug-level-report int

    -

    Debug level for the report. See +

    Debug level for the report. See --debug-level for accepted values.

    -

    --force-delete-results-dir

    +

    --force-delete-results-dir

    -

    Activates: Do not refuse to +

    Activates: Do not refuse to delete the results directory if it doesn't look like an infer results directory. (Conversely: --no-force-delete-results-dir)

    -

    --force-integration +

    --force-integration command

    -

    Proceed as if the first +

    Proceed as if the first argument after -- was command. Possible values: ant, buck1, buck, buck2, gradle, gradlew, java, javac, @@ -173,41 +173,40 @@

    OPTIONS mvn, mvnw, ndk-build, python3, rebar3, erlc, xcodebuild.

    -

    --help

    +

    --help

    -

    Show this manual

    +

    Show this manual

    -

    --help-format { auto -| groff | pager | plain }

    +

    --help-format { auto | +groff | pager | plain }

    -

    Show this help in the specified +

    Show this help in the specified format. auto sets the format to plain if the environment variable TERM is "dumb" or undefined, and to pager otherwise.

    -

    --help-full

    +

    --help-full

    -

    Show this manual with all +

    Show this manual with all internal options in the INTERNAL OPTIONS section

    -

    --keep-going

    +

    --keep-going

    -

    Activates: Keep going when the +

    Activates: Keep going when the analysis or capture encounter a failure (Conversely: --no-keep-going)

    - -

    --load-average,-l +

    --load-average,-l float

    -

    Do not start new parallel jobs +

    Do not start new parallel jobs if the load average is greater than that specified (Buck and make only)

    -

    --mark-unchanged-procs

    +

    --mark-unchanged-procs

    -

    Activates: Check structural +

    Activates: Check structural identity of newly-captured procedures with previously-captured versions, marking the new procedure as unchanged if the two are equivalent. Also prevents removing @@ -215,110 +214,109 @@

    OPTIONS reused during future incremental analyses (Conversely: --no-mark-unchanged-procs)

    -

    --merge-capture +

    --merge-capture +string

    -

    Specifies an Infer results +

    Specifies an Infer results directory. The files and procedures captured in it will be merged together into the results directory specified with -o. Relative paths are interpreted as relative to project-root/buck-out.

    -

    --never-returning-null +

    --never-returning-null json

    -

    [Java only, all analyses] +

    [Java only, all analyses] Matcher or list of matchers for functions that never return null.

    -

    --print-logs

    +

    --print-logs

    -

    Activates: Also log messages to +

    Activates: Also log messages to stdout and stderr (Conversely: --no-print-logs)

    -

    --progress-bar-style -{ auto | plain | multiline }

    +

    --progress-bar-style { +auto | plain | multiline }

    -

    Style of the progress bar. +

    Style of the progress bar. auto selects multiline if connected to a tty, otherwise plain.

    - -

    --project-root,-C +

    --project-root,-C dir

    -

    Specify the root directory of +

    Specify the root directory of the project

    -

    --python-files-index +

    --python-files-index path

    -

    A file containing a list of +

    A file containing a list of newline-separated Python files to capture. Compatible with infer capture -- python3 file1.py file2.py but not with --pyc-file.

    -

    --results-dir,-o +

    --results-dir,-o dir

    -

    Write results and internal +

    Write results and internal files in the specified directory

    -

    --run-python-interpreter

    +

    --run-python-interpreter

    -

    Activates: Capture all .py +

    Activates: Capture all .py files, transform them into internal PyIR form and run the PyIR interpreter on them. (Conversely: --no-run-python-interpreter)

    -

    --skip-analysis-in-path +

    --skip-analysis-in-path +regex

    -

    Ignore files whose path matches +

    Ignore files whose path matches a given regex (can be specified multiple times, but you must make sure each regex is properly bracketed)

    -

    --sqlite-cache-size +

    --sqlite-cache-size int

    -

    SQLite cache size in pages (if +

    SQLite cache size in pages (if positive) or kB (if negative), follows formal of corresponding SQLite PRAGMA.

    -

    --sqlite-lock-timeout +

    --sqlite-lock-timeout int

    -

    Timeout for SQLite results +

    Timeout for SQLite results database operations, in milliseconds.

    -

    --sqlite-max-blob-size +

    --sqlite-max-blob-size int

    -

    Maximum blob/string size for +

    Maximum blob/string size for data written in SQLite.

    -

    --sqlite-mmap-size +

    --sqlite-mmap-size int

    -

    Size of memory map for mmaped +

    Size of memory map for mmaped SQLite databases, zero value disables memory mapping.

    -

    --sqlite-page-size +

    --sqlite-page-size int

    -

    SQLite page size in bytes, must +

    SQLite page size in bytes, must be a power of two between 512 and 65536.

    -

    --tenv-json +

    --tenv-json file

    -

    Path to TEnv json file

    +

    Path to TEnv json file

    -

    --workspace +

    --workspace path

    -

    Specifies the root of the +

    Specifies the root of the workspace, which is a directory containing --project-root. This can be needed if the capture phase is expected to require several different @@ -328,13 +326,13 @@

    OPTIONS - + - - +

    --

    +

    Stop argument processing, use remaining arguments as a @@ -347,187 +345,186 @@

    BUCK OPTIONS -

    --append-buck-flavors +

    --append-buck-flavors +string

    -

    Additional Buck flavors to +

    Additional Buck flavors to append to targets discovered by the --buck-compilation-database option.

    -

    --buck-block-list +

    --buck-block-list +regex

    -

    Skip capture of files matched +

    Skip capture of files matched by the specified regular expression. Only the clang, non-compilation-database

    -

    Buck integration is supported, +

    Buck integration is supported, not Java.
    --buck-clang

    -

    Activates: Buck integration for +

    Activates: Buck integration for clang-based targets (C/C++/Objective-C/Objective-C++). (Conversely: --no-buck-clang)

    -

    --buck-clang-use-toolchain-config

    +

    --buck-clang-use-toolchain-config

    -

    Activates: Suppress setting +

    Activates: Suppress setting buck config values for the infer binary and other values in the buck-clang-flavor integration and instead rely on buck toolchain configuration options. (Conversely: --no-buck-clang-use-toolchain-config)

    -

    --buck-compilation-database +

    --buck-compilation-database { no-deps | deps }

    -

    Buck integration using the +

    Buck integration using the compilation database, with or without dependencies. Only includes clang targets, as per Buck's #compilation-database flavor.

    -

    --buck-compilation-database-depth +

    --buck-compilation-database-depth int

    -

    Depth of dependencies used by +

    Depth of dependencies used by the --buck-compilation-database deps option. By default, all recursive dependencies are captured.

    -

    --buck-dependency-depth +

    --buck-dependency-depth int

    -

    Capture dependencies only if +

    Capture dependencies only if they are at most the depth provided, or all transitive dependencies if depth is not provided (the default). In particular, depth zero means capture exactly the targets provided and nothing else.

    -

    --buck-erlang

    +

    --buck-erlang

    -

    Activates: Buck integration for +

    Activates: Buck integration for Erlang. (Conversely: --no-buck-erlang)

    -

    --buck-java

    +

    --buck-java

    -

    Activates: Buck integration for +

    Activates: Buck integration for Java. (Conversely: --no-buck-java)

    - -

    --buck-java-heap-size-gb +

    --buck-java-heap-size-gb int

    -

    Explicitly set the size of the +

    Explicitly set the size of the Java heap of Buck processes, in gigabytes.

    -

    --buck-java-suppress-config

    +

    --buck-java-suppress-config

    -

    Activates: Suppress setting +

    Activates: Suppress setting buck config values for the infer binary and its version in the buck-java integration. (Conversely: --no-buck-java-suppress-config)

    -

    --buck-merge-all-deps

    +

    --buck-merge-all-deps

    -

    Activates: Find and merge all +

    Activates: Find and merge all infer dependencies produced by buck. Use this flag if infer doesn't find any files to analyze after a successful capture. Only valid for --buck-clang. (Conversely: --no-buck-merge-all-deps)

    -

    --buck-targets-block-list +

    --buck-targets-block-list +regex

    -

    Skip capture of buck targets +

    Skip capture of buck targets matched by the specified regular expression.

    -

    --buck2-bxl-capture-file-block-list +

    --buck2-bxl-capture-file-block-list +regex

    -

    Skip capture of files matched +

    Skip capture of files matched by the specified regular expression. Only the clang, Buck2 integration is supported, not Java.

    -

    --buck2-bxl-target +

    --buck2-bxl-target string

    -

    Buck2 BXL script (as a buck +

    Buck2 BXL script (as a buck target) to run when capturing with buck2/clang integration.

    -

    --buck2-inferconfig-target +

    --buck2-inferconfig-target string

    -

    Buck2 target representing the +

    Buck2 target representing the inferconfig file; used in BXL capture.

    -

    --buck2-infertoolchain-target +

    --buck2-infertoolchain-target string

    -

    Buck2 target representing the +

    Buck2 target representing the infer toolchain; used in BXL capture.

    -

    --buck2-isolation-dir +

    --buck2-isolation-dir string

    -

    Run buck bxl capture with the +

    Run buck bxl capture with the given isolation directory as parameter.

    -

    --no-buck2-query-deps

    +

    --no-buck2-query-deps

    -

    Deactivates: Query deps of +

    Deactivates: Query deps of given targets and run capture on the result (alternatively run capture on given targets) (Conversely: --buck2-query-deps)

    -

    --buck2-root +

    --buck2-root dir

    -

    Specify the parent directory of +

    Specify the parent directory of buck-out (used only for buck2).

    -

    --Xbuck +

    --Xbuck +string

    -

    Pass values as command-line +

    Pass values as command-line arguments to invocations of ‘buck build‘. Only valid for --buck-clang.

    -

    --Xbuck-no-inline +

    --Xbuck-no-inline +string

    -

    Pass values as command-line +

    Pass values as command-line arguments to invocations of ‘buck build‘, don't inline any args starting with '@'. Only valid for --buck-clang.

    -

    --Xbuck2 +

    --Xbuck2 +string

    -

    Pass values as command-line +

    Pass values as command-line arguments to invocations of ‘buck2 build‘. Only valid for --buck-clang.

    -

    --Xbuck2-no-inline +

    --Xbuck2-no-inline +string

    -

    Pass values as command-line +

    Pass values as command-line arguments to invocations of ‘buck2 build‘, don't inline any args starting with '@'. Only valid for --buck-clang.

    -

    --xcode-developer-dir +

    --xcode-developer-dir XCODE_DEVELOPER_DIR

    -

    Specify the path to Xcode +

    Specify the path to Xcode developer directory, to use for Buck clang targets

    CLANG OPTIONS @@ -536,121 +533,121 @@

    CLANG OPTIONS -

    --clang-biniou-file +

    --clang-biniou-file file

    -

    Specify a file containing the +

    Specify a file containing the AST of the program, in biniou format. Please note you still need to provide a compilation command.

    -

    --clang-block-listed-flags +

    --clang-block-listed-flags +string

    -

    Clang flags to filter out

    +

    Clang flags to filter out

    -

    --clang-block-listed-flags-with-arg +

    --clang-block-listed-flags-with-arg +string

    -

    Clang flags (taking args) to +

    Clang flags (taking args) to filter out

    -

    --clang-compound-literal-init-limit +

    --clang-compound-literal-init-limit int

    -

    Limit after which +

    Limit after which initialization of compound types (structs and arrays) is not done element by element but using a builtin function that each analysis has to model.

    -

    --clang-yojson-file +

    --clang-yojson-file file

    -

    Specify a file containing the +

    Specify a file containing the AST of the program, in yojson format. Please note you still need to provide a compilation command.

    -

    --compilation-database +

    --compilation-database +path

    -

    File that contain compilation +

    File that contain compilation commands (can be specified multiple times)

    -

    --compilation-database-escaped +

    --compilation-database-escaped +path

    -

    File that contain compilation +

    File that contain compilation commands where all entries are escaped for the shell, eg coming from Xcode (can be specified multiple times)

    -

    --no-cxx

    +

    --no-cxx

    -

    Deactivates: Analyze C++ +

    Deactivates: Analyze C++ methods (Conversely: --cxx)

    -

    --dump-duplicate-symbols

    +

    --dump-duplicate-symbols

    -

    Activates: Dump all symbols +

    Activates: Dump all symbols with the same name that are defined in more than one file. (Conversely: --no-dump-duplicate-symbols)

    -

    --frontend-tests

    +

    --frontend-tests

    -

    Activates: Save +

    Activates: Save filename.ext.test.dot with the cfg in dotty format for frontend tests (also sets --print-types) (Conversely: --no-frontend-tests)

    -

    --headers

    +

    --headers

    -

    Activates: Analyze code in +

    Activates: Analyze code in header files (Conversely: --no-headers)

    -

    --objc-synthesize-dealloc

    +

    --objc-synthesize-dealloc

    -

    Activates: If enabled, the +

    Activates: If enabled, the capture tries to synthesize code in the dealloc methods of Objective-C classes corresponding to what the compiler does. (Conversely: --no-objc-synthesize-dealloc)

    -

    --skip-non-capture-clang-commands

    +

    --skip-non-capture-clang-commands

    -

    Activates: Skip clang commands +

    Activates: Skip clang commands that Infer doesn't use to capture data (Conversely: --no-skip-non-capture-clang-commands)

    -

    --skip-translation-headers +

    --skip-translation-headers +path_regex

    -

    Ignore declarations in headers +

    Ignore declarations in headers whose path matches the given OCaml regex from the start of the string during capture.

    -

    --struct-as-cpp-class

    +

    --struct-as-cpp-class

    -

    Activates: Translate C structs +

    Activates: Translate C structs as C++ classes. This can be useful when analyzing C/C++ code to make sure struct global variables shared between C and C++ source files are treated as same variables

    -

    (Conversely: +

    (Conversely: --no-struct-as-cpp-class)
    --Xclang
    +string

    -

    Pass values as command-line +

    Pass values as command-line arguments to invocations of clang

    -

    --xcpretty

    +

    --xcpretty

    -

    Activates: Infer will use +

    Activates: Infer will use xcpretty together with xcodebuild to analyze an iOS app. xcpretty just needs to be in the path, infer command is still just ‘infer -- <xcodebuild @@ -663,44 +660,44 @@

    ERLANG OPTIONS -

    --erlang-ast-dir +

    --erlang-ast-dir dir

    -

    Also load AST from all .json +

    Also load AST from all .json files in the given path. These .json files usually come from a previous run with --debug.

    -

    --erlang-check-return

    +

    --erlang-check-return

    -

    Activates: Check whether the +

    Activates: Check whether the values returned by functions correspond to what the function's spec promises. This check is introduced at capture time. (Conversely: --no-erlang-check-return)

    -

    --no-erlang-reliability

    +

    --no-erlang-reliability

    -

    Deactivates: Analyze crashing +

    Deactivates: Analyze crashing executions. This flag affects both capture and analysis. At capture time, it encodes Erlang specs; at (Pulse) analysis time, it models Erlang exceptions (builtin or OTP ones). (Conversely: --erlang-reliability)

    -

    --erlang-skip-compile

    +

    --erlang-skip-compile

    -

    Activates: Skip running +

    Activates: Skip running compiler (erlc/rebar3), to save time. The build command is basically ignored in this case. To be used together with --erlang-ast-dir. (Conversely: --no-erlang-skip-compile)

    -

    --erlang-with-otp-specs

    +

    --erlang-with-otp-specs

    -

    Activates: [EXPERIMENTAL] Use +

    Activates: [EXPERIMENTAL] Use type specs from OTP (available in the system) to generate more precise Pulse summaries for unknown library functions. (Conversely: --no-erlang-with-otp-specs)

    @@ -711,53 +708,53 @@

    JAVA OPTIONS -

    --bootclasspath +

    --bootclasspath string

    -

    Specify the Java +

    Specify the Java bootclasspath

    -

    --dependencies

    +

    --dependencies

    -

    Activates: Translate all the +

    Activates: Translate all the dependencies during the capture. The classes in the given jar file will be translated. No sources needed. (Conversely: --no-dependencies)

    -

    --generated-classes +

    --generated-classes path

    -

    Specify where to load the +

    Specify where to load the generated class files

    -

    --java-jar-compiler +

    --java-jar-compiler path

    -

    Specify the Java compiler jar +

    Specify the Java compiler jar used to generate the bytecode

    -

    --java-version +

    --java-version int

    -

    The version of Java being used. +

    The version of Java being used. Set it to your Java version if mvn is failing.

    -

    --no-kotlin-capture

    +

    --no-kotlin-capture

    -

    Deactivates: Enable Kotlin +

    Deactivates: Enable Kotlin capture. (Conversely: --kotlin-capture)

    -

    --no-mask-sawja-exceptions

    +

    --no-mask-sawja-exceptions

    -

    Deactivates: Mask exceptions +

    Deactivates: Mask exceptions thrown by Sawja/Javalib during Java capture (Conversely: --mask-sawja-exceptions)

    -

    --no-read-java-modules

    +

    --no-read-java-modules

    -

    Deactivates: Read java modules +

    Deactivates: Read java modules file using jimage. (Conversely: --read-java-modules)

    @@ -767,10 +764,10 @@

    ENVIRONMENT -

    INFER_ARGS, +

    INFER_ARGS, INFERCONFIG, INFER_STRICT_MODE

    -

    See the ENVIRONMENT section in +

    See the ENVIRONMENT section in the manual of infer(1).

    FILES @@ -779,9 +776,9 @@

    FILES -

    .inferconfig

    +

    .inferconfig

    -

    See the FILES section in the +

    See the FILES section in the manual of infer(1).

    SEE ALSO @@ -790,7 +787,7 @@

    SEE ALSO -

    infer-analyze(1), +

    infer-analyze(1), infer-compile(1), infer-run(1)


    diff --git a/man/next/infer-compile.1.html b/man/next/infer-compile.1.html index 8c37323908a..b1b92594c9a 100644 --- a/man/next/infer-compile.1.html +++ b/man/next/infer-compile.1.html @@ -1,4 +1,4 @@ - + @@ -36,7 +36,7 @@

    NAME

    -

    infer-compile - +

    infer-compile - compile project from within the infer environment

    SYNOPSIS @@ -44,15 +44,15 @@

    SYNOPSIS

    -

    infer -compile -- [compile command]

    +

    infer compile +-- [compile command]

    DESCRIPTION

    -

    Intercepts +

    Intercepts compilation commands similarly to infer-capture, but simply execute these compilation commands and do not perform any translation of the source files. This can be useful to @@ -64,9 +64,9 @@

    OPTIONS -

    --debug,-g

    +

    --debug,-g

    -

    Activates: Debug mode (also +

    Activates: Debug mode (also sets --debug-level 2, --developer-mode, --print-buckets, --print-types, --reports-include-ml-loc, @@ -74,58 +74,58 @@

    OPTIONS --write-html) (Conversely: --no-debug | -G)

    -

    --debug-level +

    --debug-level level

    -

    Debug level (sets +

    Debug level (sets --bo-debug level, --debug-level-analysis level, --debug-level-capture level):

    -

    - 0: only basic debugging +

    - 0: only basic debugging enabled
    - 1: verbose debugging enabled
    - 2: very verbose debugging enabled
    --debug-level-analysis
    int

    -

    Debug level for the analysis. +

    Debug level for the analysis. See --debug-level for accepted values.

    -

    --debug-level-capture +

    --debug-level-capture int

    -

    Debug level for the capture. +

    Debug level for the capture. See --debug-level for accepted values.

    -

    --debug-level-report +

    --debug-level-report int

    -

    Debug level for the report. See +

    Debug level for the report. See --debug-level for accepted values.

    -

    --force-delete-results-dir

    +

    --force-delete-results-dir

    -

    Activates: Do not refuse to +

    Activates: Do not refuse to delete the results directory if it doesn't look like an infer results directory. (Conversely: --no-force-delete-results-dir)

    -

    --help

    +

    --help

    -

    Show this manual

    +

    Show this manual

    -

    --help-format { auto -| groff | pager | plain }

    +

    --help-format { auto | +groff | pager | plain }

    -

    Show this help in the specified +

    Show this help in the specified format. auto sets the format to plain if the environment variable TERM is "dumb" or undefined, and to pager otherwise.

    -

    --help-full

    +

    --help-full

    -

    Show this manual with all +

    Show this manual with all internal options in the INTERNAL OPTIONS section

    ENVIRONMENT @@ -134,10 +134,10 @@

    ENVIRONMENT -

    INFER_ARGS, +

    INFER_ARGS, INFERCONFIG, INFER_STRICT_MODE

    -

    See the ENVIRONMENT section in +

    See the ENVIRONMENT section in the manual of infer(1).

    FILES @@ -146,9 +146,9 @@

    FILES -

    .inferconfig

    +

    .inferconfig

    -

    See the FILES section in the +

    See the FILES section in the manual of infer(1).

    EXAMPLES @@ -156,33 +156,32 @@

    EXAMPLES

    - -

    cmake(1) +

    cmake(1) hardcodes the absolute paths to the compiler inside the Makefiles it generates, which defeats the later capture of compilation commands by infer. Thus, to capture a CMake project, one should configure the project from within the infer build environment, for instance:

    -

    mkdir build +

    mkdir build && cd build
    infer compile -- cmake ..
    infer capture -- make

    -

    The same +

    The same solution can be used for projects whose "./configure" script hardcodes the paths to the compilers, for instance:

    -

    infer compile --- ./configure
    +

    infer compile -- +./configure
    infer capture -- make

    -

    Another -solution for CMake projects is to use CMake's compilation -databases, for instance:

    +

    Another solution +for CMake projects is to use CMake's compilation databases, +for instance:

    -

    mkdir build +

    mkdir build && cd build
    cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1 ..
    infer capture --compilation-database @@ -194,7 +193,7 @@

    SEE ALSO -

    infer-capture(1)

    +

    infer-capture(1)


    diff --git a/man/next/infer-debug.1.html b/man/next/infer-debug.1.html index ab63599d46b..8f0d9f468c1 100644 --- a/man/next/infer-debug.1.html +++ b/man/next/infer-debug.1.html @@ -1,4 +1,4 @@ - + @@ -38,7 +38,7 @@

    NAME

    -

    infer-debug - +

    infer-debug - print internal infer data structures

    SYNOPSIS @@ -46,7 +46,7 @@

    SYNOPSIS

    -

    infer debug +

    infer debug --global-tenv
    infer debug --procedures
    [options]
    infer debug --source-files
    [options]

    @@ -56,19 +56,19 @@

    DESCRIPTION

    -

    If +

    If --procedures is passed, print information about each procedures captured by infer.

    -

    If +

    If --source-files is passed, print information about captured source files.

    -

    If +

    If --global-tenv is passed, print the global type environment (if any).

    -

    At least one of +

    At least one of the above options must be passed.

    OPTIONS @@ -77,35 +77,35 @@

    OPTIONS -

    --help

    +

    --help

    -

    Show this manual

    +

    Show this manual

    -

    --help-format { auto -| groff | pager | plain }

    +

    --help-format { auto | +groff | pager | plain }

    -

    Show this help in the specified +

    Show this help in the specified format. auto sets the format to plain if the environment variable TERM is "dumb" or undefined, and to pager otherwise.

    -

    --help-full

    +

    --help-full

    -

    Show this manual with all +

    Show this manual with all internal options in the INTERNAL OPTIONS section

    -

    --preanalysis-html

    +

    --preanalysis-html

    -

    Activates: Whether the HTML +

    Activates: Whether the HTML node printing for preanalysis is enabled or not. Set to false by default since this helps focus on debugging just the enabled analyses. (Conversely: --no-preanalysis-html)

    -

    --select +

    --select (N|all)

    -

    Select option number N +

    Select option number N or all of them. If omitted, prompt for input.

    DEBUG GLOBAL TYPE ENVIRONMENT @@ -114,9 +114,9 @@

    DEBUG GLOBAL TYPE ENVIRONMENT -

    --global-tenv

    +

    --global-tenv

    -

    Activates: Print the global +

    Activates: Print the global type environment. (Conversely: --no-global-tenv)

    DEBUG PROCEDURES @@ -125,59 +125,58 @@

    DEBUG PROCEDURES -

    --procedures

    +

    --procedures

    -

    Activates: Print functions and +

    Activates: Print functions and methods discovered by infer (Conversely: --no-procedures)

    -

    --procedures-attributes

    +

    --procedures-attributes

    -

    Activates: Print the attributes +

    Activates: Print the attributes of each procedure in the output of --procedures (Conversely: --no-procedures-attributes)

    -

    --procedures-call-graph

    +

    --procedures-call-graph

    -

    Activates: Output a dotty file +

    Activates: Output a dotty file in infer-out/captured/syntactic-call-graph.dot. The graph is the syntactic call graph reachable from either all captured procedures or those determined by the option --changed-files-index. (Conversely: --no-procedures-call-graph)

    +

    --procedures-callees

    -

    --procedures-callees

    - -

    Activates: Print the static +

    Activates: Print the static callees of each procedure in the output of --procedures (Conversely: --no-procedures-callees)

    -

    --procedures-cfg

    +

    --procedures-cfg

    -

    Activates: Output a dotty file +

    Activates: Output a dotty file in infer-out/captured/<file_name>/<proc_name>.dot for each procedure in the output of --procedures (Conversely: --no-procedures-cfg)

    -

    --no-procedures-definedness

    +

    --no-procedures-definedness

    -

    Deactivates: Include procedures +

    Deactivates: Include procedures definedness in the output of --procedures, i.e. whether the procedure definition was found, or only the procedure declaration, or the procedure is an auto-generated Objective-C accessor (Conversely: --procedures-definedness)

    -

    --procedures-filter +

    --procedures-filter filter

    -

    With --procedures, only +

    With --procedures, only print functions and methods (procedures) matching the specified filter. A procedure filter is of the form path_pattern:procedure_name. Patterns are interpreted @@ -185,39 +184,38 @@

    DEBUG PROCEDURES methods named "foo", one can use the filter ".*:foo", or "foo" for short.

    -

    --procedures-name

    +

    --procedures-name

    -

    Activates: Include procedures +

    Activates: Include procedures names in the output of --procedures (Conversely: --no-procedures-name)

    -

    --no-procedures-source-file

    +

    --no-procedures-source-file

    -

    Deactivates: Include the source +

    Deactivates: Include the source file in which the procedure definition or declaration was found in the output of --procedures (Conversely: --procedures-source-file)

    +

    --procedures-summary

    -

    --procedures-summary

    - -

    Activates: Print the summaries +

    Activates: Print the summaries of each procedure in the output of --procedures. See also --procedures-summary-skip-empty. (Conversely: --no-procedures-summary)

    -

    --procedures-summary-json

    +

    --procedures-summary-json

    -

    Activates: Emit the summaries +

    Activates: Emit the summaries of each procedure in the output of --procedures as JSON (Conversely: --no-procedures-summary-json)

    -

    --procedures-summary-skip-empty

    +

    --procedures-summary-skip-empty

    -

    Activates: Completely skip +

    Activates: Completely skip procedures that do not have summaries. Useful when analyzing a small part of a big project. (To use in conjunction with --procedures-summary or @@ -231,10 +229,10 @@

    DEBUG SOURCE FILES -

    --complete-capture-from +

    --complete-capture-from path

    -

    Provide the path to an infer +

    Provide the path to an infer results directory containing a capture database. The capture database specified with --results-dir) (which must exist) will be completed from the input database and @@ -242,78 +240,78 @@

    DEBUG SOURCE FILES directory. The exit code will be equal to the number of rows added to the capture database.

    -

    --extract-capture-from +

    --extract-capture-from path

    -

    Provide the path to an infer +

    Provide the path to an infer results directory containing a capture database. Together with a list of files provided through the obligatory use of --changed-files-index, create a new capture database containing only the artefacts related to these files (in the location specified with --results-dir).

    -

    --source-files

    +

    --source-files

    -

    Activates: Print source files +

    Activates: Print source files discovered by infer (Conversely: --no-source-files)

    -

    --source-files-call-graph

    +

    --source-files-call-graph

    -

    Activates: Output a dotty file +

    Activates: Output a dotty file in infer-out/captured/file-call-graph.dot. The graph is the file-based syntactic call graph of all captured procedures (with known translation units). (Conversely: --no-source-files-call-graph)

    -

    --source-files-call-graph-partition +

    --source-files-call-graph-partition int

    -

    The number of partitions to +

    The number of partitions to divide the set of captured source files, using static call graph information. The generated file lists are found under infer-out/captured/workerXX.idx. Not setting this option skips partitioning. This is used for distributed analysis.

    -

    --source-files-cfg

    +

    --source-files-cfg

    -

    Activates: Output a dotty file +

    Activates: Output a dotty file in infer-out/captured for each source file in the output of --source-files (Conversely: --no-source-files-cfg)

    -

    --source-files-filter +

    --source-files-filter filter

    -

    With --source-files, +

    With --source-files, only print source files matching the specified filter. The filter is a pattern that should match the file path. Patterns are interpreted as OCaml Str regular expressions.

    -

    --source-files-freshly-captured

    +

    --source-files-freshly-captured

    -

    Activates: Print whether the +

    Activates: Print whether the source file has been captured in the most recent capture phase in the output of --source-files. (Conversely: --no-source-files-freshly-captured)

    -

    --source-files-procedure-names

    +

    --source-files-procedure-names

    -

    Activates: Print the names of +

    Activates: Print the names of procedure of each source file in the output of --source-files (Conversely: --no-source-files-procedure-names)

    -

    --source-files-type-environment

    +

    --source-files-type-environment

    -

    Activates: Print the type +

    Activates: Print the type environment of each source file in the output of --source-files (Conversely: --no-source-files-type-environment)

    @@ -324,10 +322,10 @@

    ENVIRONMENT -

    INFER_ARGS, +

    INFER_ARGS, INFERCONFIG, INFER_STRICT_MODE

    -

    See the ENVIRONMENT section in +

    See the ENVIRONMENT section in the manual of infer(1).

    FILES @@ -336,9 +334,9 @@

    FILES -

    .inferconfig

    +

    .inferconfig

    -

    See the FILES section in the +

    See the FILES section in the manual of infer(1).

    SEE ALSO @@ -347,7 +345,7 @@

    SEE ALSO -

    infer-explore(1), +

    infer-explore(1), infer-report(1)


    diff --git a/man/next/infer-explore.1.html b/man/next/infer-explore.1.html index fb8c0d830d9..9cb32449bd3 100644 --- a/man/next/infer-explore.1.html +++ b/man/next/infer-explore.1.html @@ -1,4 +1,4 @@ - + @@ -36,7 +36,7 @@

    NAME

    -

    infer-explore - +

    infer-explore - explore the error traces in infer reports

    SYNOPSIS @@ -44,7 +44,7 @@

    SYNOPSIS

    -

    infer +

    infer explore [options]

    DESCRIPTION @@ -52,8 +52,8 @@

    DESCRIPTION

    -

    Show the list -of bugs on the console and explore symbolic program traces +

    Show the list of +bugs on the console and explore symbolic program traces emitted by infer to explain a report. Can also generate an HTML report from a JSON report.

    @@ -63,27 +63,27 @@

    OPTIONS -

    --help

    +

    --help

    -

    Show this manual

    +

    Show this manual

    -

    --help-format { auto -| groff | pager | plain }

    +

    --help-format { auto | +groff | pager | plain }

    -

    Show this help in the specified +

    Show this help in the specified format. auto sets the format to plain if the environment variable TERM is "dumb" or undefined, and to pager otherwise.

    -

    --help-full

    +

    --help-full

    -

    Show this manual with all +

    Show this manual with all internal options in the INTERNAL OPTIONS section

    -

    --results-dir,-o +

    --results-dir,-o dir

    -

    Write results and internal +

    Write results and internal files in the specified directory

    EXPLORE BUGS @@ -92,27 +92,27 @@

    EXPLORE BUGS -

    --html

    +

    --html

    -

    Activates: Generate an html +

    Activates: Generate an html report of issues found. (Conversely: --no-html)

    -

    --max-nesting +

    --max-nesting int

    -

    Level of nested procedure calls +

    Level of nested procedure calls to show. Trace elements beyond the maximum nesting level are skipped. If omitted, all levels are shown.

    -

    --select +

    --select (N|all)

    -

    Select option number N +

    Select option number N or all of them. If omitted, prompt for input.

    -

    --no-source-preview

    +

    --no-source-preview

    -

    Deactivates: print code +

    Deactivates: print code excerpts around trace elements (Conversely: --source-preview)

    @@ -122,10 +122,10 @@

    ENVIRONMENT -

    INFER_ARGS, +

    INFER_ARGS, INFERCONFIG, INFER_STRICT_MODE

    -

    See the ENVIRONMENT section in +

    See the ENVIRONMENT section in the manual of infer(1).

    FILES @@ -134,9 +134,9 @@

    FILES -

    .inferconfig

    +

    .inferconfig

    -

    See the FILES section in the +

    See the FILES section in the manual of infer(1).

    SEE ALSO @@ -145,7 +145,7 @@

    SEE ALSO -

    infer-report(1), +

    infer-report(1), infer-run(1)


    diff --git a/man/next/infer-help.1.html b/man/next/infer-help.1.html index d815ae60acb..cf9c1e7fc3d 100644 --- a/man/next/infer-help.1.html +++ b/man/next/infer-help.1.html @@ -1,4 +1,4 @@ - + @@ -34,7 +34,7 @@

    NAME

    -

    infer-help - +

    infer-help - Show and generate documentation.

    SYNOPSIS @@ -42,7 +42,7 @@

    SYNOPSIS

    -

    infer help +

    infer help
    infer help --help-checker
    checker1 ... --help-checker checkerN
    @@ -57,24 +57,24 @@

    DESCRIPTION

    -

    Without +

    Without arguments, show the Infer manual as with infer --help

    -

    For each +

    For each -help-checker or --help-issue-type option passed, display information about the given checker or issue type.

    -

    If +

    If --list-checkers is passed, list all available checkers.

    -

    If +

    If --list-issue-types is passed, list all issue types.

    -

    Use +

    Use --write-website to build some of the documentation for the fbinfer.com website. (Used in scripts, not meant to be used except when publishing content to @@ -86,59 +86,59 @@

    OPTIONS -

    --help

    +

    --help

    -

    Show this manual

    +

    Show this manual

    -

    --help-checker +

    --help-checker +checker-id

    -

    Show information about a +

    Show information about a checker, for example biabduction. To see the list of all checkers, see --list-checkers.

    -

    --help-format { auto -| groff | pager | plain }

    +

    --help-format { auto | +groff | pager | plain }

    -

    Show this help in the specified +

    Show this help in the specified format. auto sets the format to plain if the environment variable TERM is "dumb" or undefined, and to pager otherwise.

    -

    --help-full

    +

    --help-full

    -

    Show this manual with all +

    Show this manual with all internal options in the INTERNAL OPTIONS section

    -

    --help-issue-type +

    --help-issue-type +UNIQUE_ID

    -

    Show information about an issue +

    Show information about an issue type, for example NULL_DEREFERENCE. To see the list of all issue types, see --list-issue-types.

    -

    --list-categories

    +

    --list-categories

    -

    Activates: Show the list of all +

    Activates: Show the list of all categories of issue types that infer might report. (Conversely: --no-list-categories)

    -

    --list-checkers

    +

    --list-checkers

    -

    Activates: Show the list of all +

    Activates: Show the list of all available checkers. (Conversely: --no-list-checkers)

    -

    --list-issue-types

    +

    --list-issue-types

    -

    Activates: Show the list of all +

    Activates: Show the list of all issue types that infer might report. (Conversely: --no-list-issue-types)

    -

    --write-website +

    --write-website path_to_website_dir

    -

    Use to write website files +

    Use to write website files documenting issue types and checkers under path_to_website_dir/. Meant to be used within the Infer directory to generate its website at @@ -150,10 +150,10 @@

    ENVIRONMENT -

    INFER_ARGS, +

    INFER_ARGS, INFERCONFIG, INFER_STRICT_MODE

    -

    See the ENVIRONMENT section in +

    See the ENVIRONMENT section in the manual of infer(1).

    FILES @@ -162,9 +162,9 @@

    FILES -

    .inferconfig

    +

    .inferconfig

    -

    See the FILES section in the +

    See the FILES section in the manual of infer(1).


    diff --git a/man/next/infer-report.1.html b/man/next/infer-report.1.html index 6eb4338093f..eb292ec4841 100644 --- a/man/next/infer-report.1.html +++ b/man/next/infer-report.1.html @@ -1,4 +1,4 @@ - + @@ -38,7 +38,7 @@

    NAME

    -

    infer-report - +

    infer-report - compute and manipulate infer reports

    SYNOPSIS @@ -46,7 +46,7 @@

    SYNOPSIS

    -

    infer report +

    infer report
    infer report --issues-tests
    infer report --cost-issues-tests
    @@ -59,7 +59,7 @@

    DESCRIPTION

    -

    When used +

    When used without parameters, generate report output in Json. With a --tests parameter, write out issues in a format suitable for tests. With --merge-report, merge @@ -71,17 +71,17 @@

    OPTIONS -

    --no-censor-report +

    --no-censor-report +issue_type_regex

    -

    For debugging/experimentation +

    For debugging/experimentation only: Specify issues not to be censored by --censor-report.

    -

    --censor-report +

    --censor-report +string

    -

    Specify a filter for issues to +

    Specify a filter for issues to be censored by adding a 'censored_reason' field in the json report. Infer will not report censored issues on the console output and in report.txt, but tools that post-process the @@ -105,36 +105,36 @@

    OPTIONS used to explain why the issue was filtered.

    -

    --config-impact-data-file +

    --config-impact-data-file file

    -

    [ConfigImpact] Specify the file +

    [ConfigImpact] Specify the file containing the config data

    -

    --config-impact-issues-tests +

    --config-impact-issues-tests file

    -

    Write a list of config impact +

    Write a list of config impact issues in a format suitable for config impact tests to file

    -

    --config-impact-max-callees-to-print +

    --config-impact-max-callees-to-print int

    -

    Specify the maximum number of +

    Specify the maximum number of unchecked callees to print in the config impact checker

    -

    --cost-issues-tests +

    --cost-issues-tests file

    -

    Write a list of cost issues in +

    Write a list of cost issues in a format suitable for cost tests to file

    -

    --debug,-g

    +

    --debug,-g

    -

    Activates: Debug mode (also +

    Activates: Debug mode (also sets --debug-level 2, --developer-mode, --print-buckets, --print-types, --reports-include-ml-loc, @@ -142,61 +142,61 @@

    OPTIONS --write-html) (Conversely: --no-debug | -G)

    -

    --debug-level +

    --debug-level level

    -

    Debug level (sets +

    Debug level (sets --bo-debug level, --debug-level-analysis level, --debug-level-capture level):

    -

    - 0: only basic debugging +

    - 0: only basic debugging enabled
    - 1: verbose debugging enabled
    - 2: very verbose debugging enabled
    --debug-level-analysis
    int

    -

    Debug level for the analysis. +

    Debug level for the analysis. See --debug-level for accepted values.

    -

    --debug-level-capture +

    --debug-level-capture int

    -

    Debug level for the capture. +

    Debug level for the capture. See --debug-level for accepted values.

    -

    --debug-level-report +

    --debug-level-report int

    -

    Debug level for the report. See +

    Debug level for the report. See --debug-level for accepted values.

    -

    --no-deduplicate

    +

    --no-deduplicate

    -

    Deactivates: Apply +

    Deactivates: Apply issue-specific deduplication during analysis and/or reporting. (Conversely: --deduplicate)

    -

    --differential-filter-files +

    --differential-filter-files string

    -

    Specify the file containing the +

    Specify the file containing the list of source files for which a differential report is desired. Source files should be specified relative to project root or be absolute

    -

    --disable-issue-type +

    --disable-issue-type +issue_type

    -

    Do not show reports coming from +

    Do not show reports coming from this type of issue. Each checker can report a range of issue types. This option provides fine-grained filtering over which types of issue should be reported once the checkers have run. In particular, note that disabling issue types does not make the corresponding checker not run.

    -

    Available issue types are as +

    Available issue types are as follows:
    ARBITRARY_CODE_EXECUTION_UNDER_LOCK (enabled by default),
    @@ -280,6 +280,7 @@

    OPTIONS INFERBO_ALLOC_MAY_BE_BIG (enabled by default),
    INFERBO_ALLOC_MAY_BE_NEGATIVE (enabled by default),
    INFINITE_EXECUTION_TIME (disabled by default),
    +INFINITE_RECURSION (disabled by default),
    INHERENTLY_DANGEROUS_FUNCTION (enabled by default),
    INTEGER_OVERFLOW_L1 (enabled by default),
    INTEGER_OVERFLOW_L2 (enabled by default),
    @@ -294,6 +295,7 @@

    OPTIONS LINEAGE_FLOW (enabled by default),
    LOCKLESS_VIOLATION (enabled by default),
    LOCK_CONSISTENCY_VIOLATION (enabled by default),
    +LOCK_ON_UI_THREAD (disabled by default),
    Leak_after_array_abstraction (enabled by default),
    Leak_in_footprint (enabled by default),
    Leak_unknown_origin (disabled by default),
    @@ -408,7 +410,7 @@

    OPTIONS Wrong_argument_number (enabled by default).
    --enable-issue-type
    +issue_type

    -

    Show reports coming from this +

    Show reports coming from this type of issue. By default, all issue types are enabled except the ones listed in --disable-issue-type. Note that enabling issue types does not make the corresponding @@ -416,57 +418,56 @@

    OPTIONS or off.

    -

    --no-filtering,-F

    +

    --no-filtering,-F

    -

    Deactivates: Do not show the +

    Deactivates: Do not show the experimental and block listed issue types (Conversely: --filtering | -f)

    -

    --from-json-config-impact-report +

    --from-json-config-impact-report config-impact-report.json

    -

    Load costs analysis results +

    Load costs analysis results from a config-impact-report file.

    - -

    --from-json-costs-report +

    --from-json-costs-report costs-report.json

    -

    Load costs analysis results +

    Load costs analysis results from a costs-report file.

    -

    --from-json-report +

    --from-json-report report.json

    -

    Load analysis results from a +

    Load analysis results from a report file (default is to load the results from the specs files generated by the analysis).

    -

    --help

    +

    --help

    -

    Show this manual

    +

    Show this manual

    -

    --help-format { auto -| groff | pager | plain }

    +

    --help-format { auto | +groff | pager | plain }

    -

    Show this help in the specified +

    Show this help in the specified format. auto sets the format to plain if the environment variable TERM is "dumb" or undefined, and to pager otherwise.

    -

    --help-full

    +

    --help-full

    -

    Show this manual with all +

    Show this manual with all internal options in the INTERNAL OPTIONS section

    -

    --issues-tests +

    --issues-tests file

    -

    Write a list of issues in a +

    Write a list of issues in a format suitable for tests to file

    -

    --issues-tests-fields +

    --issues-tests-fields ,-separated sequence of { bug_type | bucket |
    qualifier | suggestion | severity | line | column | procedure |
    @@ -476,76 +477,74 @@

    OPTIONS
    transitive_callees_extra | suppressed | autofix }

    -

    Fields to emit with +

    Fields to emit with --issues-tests

    -

    --merge-report +

    --merge-report +string

    -

    Specifies an Infer results +

    Specifies an Infer results directory. The reports stored in JSON files in all specified results directories will be merged together and deduplicated before being stored in the main results directory.

    -

    --merge-summaries +

    --merge-summaries +string

    -

    Specifies an Infer results +

    Specifies an Infer results directory. The summaries in all specified results directories will be merged together and deduplicated before reporting is done.

    -

    --print-logs

    +

    --print-logs

    -

    Activates: Also log messages to +

    Activates: Also log messages to stdout and stderr (Conversely: --no-print-logs)

    - -

    --project-root,-C +

    --project-root,-C dir

    -

    Specify the root directory of +

    Specify the root directory of the project

    -

    --quiet,-q

    +

    --quiet,-q

    -

    Activates: Do not print +

    Activates: Do not print anything on standard output. (Conversely: --no-quiet | -Q)

    -

    --report-allow-list-path-regex +

    --report-allow-list-path-regex +path_regex

    -

    Report issues only on files +

    Report issues only on files whose relative path matches the specified OCaml regex (and which do not match --report-block-list-path-regex)

    -

    --report-block-list-files-containing +

    --report-block-list-files-containing +string

    -

    Do not report any issues on +

    Do not report any issues on files containing the specified string

    -

    --report-block-list-path-regex +

    --report-block-list-path-regex +path_regex

    -

    Do not report any issues on +

    Do not report any issues on files whose relative path matches the specified OCaml regex, even if they match the allow list specified by --report-allow-list-path-regex

    - -

    --report-block-list-spec +

    --report-block-list-spec json

    -

    Do not report the issues in +

    Do not report the issues in this list.

    -

    Example format:
    +

    Example format:
    "report-block-list-spec": [
    { "bug_type": "CXX_REF_CAPTURED_IN_BLOCK",
    @@ -562,40 +561,39 @@

    OPTIONS ]
    --report-console-limit
    int

    -

    Maximum number of issues to +

    Maximum number of issues to display on standard output. Unset with --report-console-limit-reset to show all.

    -

    --report-formatter { +

    --report-formatter { none | phabricator }

    -

    Which formatter to use when +

    Which formatter to use when emitting the report

    - -

    --report-suppress-errors +

    --report-suppress-errors +error_name

    -

    do not report a type of +

    do not report a type of errors

    -

    --results-dir,-o +

    --results-dir,-o dir

    -

    Write results and internal +

    Write results and internal files in the specified directory

    -

    --skip-analysis-in-path-skips-compilation

    +

    --skip-analysis-in-path-skips-compilation

    -

    Activates: Whether paths in +

    Activates: Whether paths in --skip-analysis-in-path should be compiled or not (Conversely: --no-skip-analysis-in-path-skips-compilation)

    -

    --no-suppressions

    +

    --no-suppressions

    -

    Deactivates: Suppress infer +

    Deactivates: Suppress infer issues on source lines matching the @infer-disable ISSUE_TYPE1, ISSUE_TYPE2, ... and @infer-disable-every ISSUE_TYPE1, ISSUE_TYPE2, ... keywords. (Conversely: @@ -607,9 +605,9 @@

    HOISTING OPTIONS -

    --no-hoisting-report-only-expensive

    +

    --no-hoisting-report-only-expensive

    -

    Deactivates: [Hoisting] Report +

    Deactivates: [Hoisting] Report loop-invariant calls only when the function is expensive, i.e. at least linear (Conversely: --hoisting-report-only-expensive)

    @@ -620,22 +618,22 @@

    LINEAGE OPTIONS -

    --lineage-sanitizers +

    --lineage-sanitizers +string

    -

    [EXPERIMENTAL; UNSTABLE API] +

    [EXPERIMENTAL; UNSTABLE API] Lineage sanitizers, comma-separated m:f/a

    -

    --lineage-sink +

    --lineage-sink +string

    -

    [EXPERIMENTAL; UNSTABLE API] +

    [EXPERIMENTAL; UNSTABLE API] Lineage sinks for taint finding, format [module:]function/arity.{ret,argN}, comma-separated. Must be used with --lineage-source as options to the report subcommand.

    -

    Will produce a graph +

    Will produce a graph materializing the flows between the sources
    and the sinks along with a json issues file. The issues file will
    @@ -646,11 +644,11 @@

    LINEAGE OPTIONS files containing those results.
    --lineage-source
    +string

    -

    [EXPERIMENTAL; UNSTABLE API] +

    [EXPERIMENTAL; UNSTABLE API] Lineage sources for taint finding, format [module:]function/arity.{ret,argN}, comma-separated.

    -

    See --lineage-sink for +

    See --lineage-sink for additional documentation.

    PULSE CHECKER OPTIONS @@ -659,17 +657,17 @@

    PULSE CHECKER OPTIONS -

    --pulse-report-flows-from-taint-source +

    --pulse-report-flows-from-taint-source procname

    -

    Report data flows which +

    Report data flows which originate at taint source procname

    -

    --pulse-report-flows-to-taint-sink +

    --pulse-report-flows-to-taint-sink procname

    -

    Report data flows which pass +

    Report data flows which pass through taint sink procname

    ENVIRONMENT @@ -678,10 +676,10 @@

    ENVIRONMENT -

    INFER_ARGS, +

    INFER_ARGS, INFERCONFIG, INFER_STRICT_MODE

    -

    See the ENVIRONMENT section in +

    See the ENVIRONMENT section in the manual of infer(1).

    FILES @@ -690,9 +688,9 @@

    FILES -

    .inferconfig

    +

    .inferconfig

    -

    See the FILES section in the +

    See the FILES section in the manual of infer(1).

    SEE ALSO @@ -701,7 +699,7 @@

    SEE ALSO -

    infer-reportdiff(1), +

    infer-reportdiff(1), infer-run(1)


    diff --git a/man/next/infer-reportdiff.1.html b/man/next/infer-reportdiff.1.html index be62af6b9d2..aabe45cf8d1 100644 --- a/man/next/infer-reportdiff.1.html +++ b/man/next/infer-reportdiff.1.html @@ -1,4 +1,4 @@ - + @@ -36,7 +36,7 @@

    NAME -

    infer-reportdiff +

    infer-reportdiff - compute the differences between two infer reports

    SYNOPSIS @@ -44,7 +44,7 @@

    SYNOPSIS

    -

    infer +

    infer reportdiff --report-current file --report-previous file [options]

    @@ -53,7 +53,7 @@

    DESCRIPTION

    -

    Given two infer +

    Given two infer reports previous and current, compute the following three reports and store them inside the "differential/" subdirectory of the results @@ -65,7 +65,7 @@

    DESCRIPTION - preexisting.json contains the issues found in both previous and current.

    -

    All three files +

    All three files follow the same format as normal infer reports.

    OPTIONS @@ -74,41 +74,40 @@

    OPTIONS -

    --config-impact-current +

    --config-impact-current path

    -

    Config impact report of the +

    Config impact report of the latest revision

    -

    --config-impact-max-callees-to-print +

    --config-impact-max-callees-to-print int

    -

    Specify the maximum number of +

    Specify the maximum number of unchecked callees to print in the config impact checker

    - -

    --config-impact-previous +

    --config-impact-previous path

    -

    Config impact report of the +

    Config impact report of the base revision to use for comparison

    -

    --costs-current +

    --costs-current path

    -

    Costs report of the latest +

    Costs report of the latest revision

    -

    --costs-previous +

    --costs-previous path

    -

    Costs report of the base +

    Costs report of the base revision to use for comparison

    -

    --debug,-g

    +

    --debug,-g

    -

    Activates: Debug mode (also +

    Activates: Debug mode (also sets --debug-level 2, --developer-mode, --print-buckets, --print-types, --reports-include-ml-loc, @@ -116,97 +115,97 @@

    OPTIONS --write-html) (Conversely: --no-debug | -G)

    -

    --debug-level +

    --debug-level level

    -

    Debug level (sets +

    Debug level (sets --bo-debug level, --debug-level-analysis level, --debug-level-capture level):

    -

    - 0: only basic debugging +

    - 0: only basic debugging enabled
    - 1: verbose debugging enabled
    - 2: very verbose debugging enabled
    --debug-level-analysis
    int

    -

    Debug level for the analysis. +

    Debug level for the analysis. See --debug-level for accepted values.

    -

    --debug-level-capture +

    --debug-level-capture int

    -

    Debug level for the capture. +

    Debug level for the capture. See --debug-level for accepted values.

    -

    --debug-level-report +

    --debug-level-report int

    -

    Debug level for the report. See +

    Debug level for the report. See --debug-level for accepted values.

    -

    --no-deduplicate

    +

    --no-deduplicate

    -

    Deactivates: Apply +

    Deactivates: Apply issue-specific deduplication during analysis and/or reporting. (Conversely: --deduplicate)

    -

    --file-renamings +

    --file-renamings path

    -

    JSON with a list of file +

    JSON with a list of file renamings to use while computing differential reports

    -

    --help

    +

    --help

    -

    Show this manual

    +

    Show this manual

    -

    --help-format { auto -| groff | pager | plain }

    +

    --help-format { auto | +groff | pager | plain }

    -

    Show this help in the specified +

    Show this help in the specified format. auto sets the format to plain if the environment variable TERM is "dumb" or undefined, and to pager otherwise.

    -

    --help-full

    +

    --help-full

    -

    Show this manual with all +

    Show this manual with all internal options in the INTERNAL OPTIONS section

    -

    --report-current +

    --report-current path

    -

    report of the latest +

    report of the latest revision

    -

    --report-previous +

    --report-previous path

    -

    Report of the base revision to +

    Report of the base revision to use for comparison

    -

    --no-skip-duplicated-types

    +

    --no-skip-duplicated-types

    -

    Deactivates: Skip +

    Deactivates: Skip fixed-then-introduced duplicated types while computing differential reports (Conversely: --skip-duplicated-types)

    -

    --stats-dir-current +

    --stats-dir-current path

    -

    The infer-out/stats from the +

    The infer-out/stats from the current run. Together with --stats-dir-previous, make infer reportdiff compute the difference between two stats directories and output the results in infer-out/differential/stats_*.json files.

    -

    --stats-dir-previous +

    --stats-dir-previous path

    -

    The infer-out/stats from a +

    The infer-out/stats from a previous run. See --stats-dir-current.

    ENVIRONMENT @@ -215,10 +214,10 @@

    ENVIRONMENT -

    INFER_ARGS, +

    INFER_ARGS, INFERCONFIG, INFER_STRICT_MODE

    -

    See the ENVIRONMENT section in +

    See the ENVIRONMENT section in the manual of infer(1).

    FILES @@ -227,9 +226,9 @@

    FILES -

    .inferconfig

    +

    .inferconfig

    -

    See the FILES section in the +

    See the FILES section in the manual of infer(1).

    SEE ALSO @@ -238,7 +237,7 @@

    SEE ALSO -

    infer-report(1)

    +

    infer-report(1)


    diff --git a/man/next/infer-run.1.html b/man/next/infer-run.1.html index ed14f457e28..9bcbac73bfd 100644 --- a/man/next/infer-run.1.html +++ b/man/next/infer-run.1.html @@ -1,4 +1,4 @@ - + @@ -36,7 +36,7 @@

    NAME

    -

    infer-run - +

    infer-run - capture source files, analyze, and report

    SYNOPSIS @@ -44,8 +44,8 @@

    SYNOPSIS

    -

    infer -run [options]
    +

    infer run +[options]
    infer
    [options] -- compile command

    @@ -54,11 +54,11 @@

    DESCRIPTION

    -

    Calling +

    Calling "infer run [options]" is equivalent to performing the following sequence of commands:

    -

    infer +

    infer capture [options]
    infer analyze
    [options]

    @@ -68,24 +68,24 @@

    OPTIONS -

    --capture-block-list +

    --capture-block-list json

    -

    Matcher or list of matchers for +

    Matcher or list of matchers for names of files that should not be captured, hence not analyzed either. Clang, Java, and Hack only.

    -

    --no-censor-report +

    --no-censor-report +issue_type_regex

    -

    For debugging/experimentation +

    For debugging/experimentation only: Specify issues not to be censored by --censor-report.

    -

    --censor-report +

    --censor-report +string

    -

    Specify a filter for issues to +

    Specify a filter for issues to be censored by adding a 'censored_reason' field in the json report. Infer will not report censored issues on the console output and in report.txt, but tools that post-process the @@ -108,9 +108,9 @@

    OPTIONS ‘<reason_string>‘ is a non-empty string used to explain why the issue was filtered.

    -

    --debug,-g

    +

    --debug,-g

    -

    Activates: Debug mode (also +

    Activates: Debug mode (also sets --debug-level 2, --developer-mode, --print-buckets, --print-types, --reports-include-ml-loc, @@ -118,53 +118,53 @@

    OPTIONS --write-html) (Conversely: --no-debug | -G)

    -

    --debug-level +

    --debug-level level

    -

    Debug level (sets +

    Debug level (sets --bo-debug level, --debug-level-analysis level, --debug-level-capture level):

    -

    - 0: only basic debugging +

    - 0: only basic debugging enabled
    - 1: verbose debugging enabled
    - 2: very verbose debugging enabled
    --debug-level-analysis
    int

    -

    Debug level for the analysis. +

    Debug level for the analysis. See --debug-level for accepted values.

    -

    --debug-level-capture +

    --debug-level-capture int

    -

    Debug level for the capture. +

    Debug level for the capture. See --debug-level for accepted values.

    -

    --debug-level-report +

    --debug-level-report int

    -

    Debug level for the report. See +

    Debug level for the report. See --debug-level for accepted values.

    -

    --fail-on-issue

    +

    --fail-on-issue

    -

    Activates: Exit with error code +

    Activates: Exit with error code 2 if Infer found something to report (Conversely: --no-fail-on-issue)

    -

    --force-delete-results-dir

    +

    --force-delete-results-dir

    -

    Activates: Do not refuse to +

    Activates: Do not refuse to delete the results directory if it doesn't look like an infer results directory. (Conversely: --no-force-delete-results-dir)

    -

    --force-integration +

    --force-integration command

    -

    Proceed as if the first +

    Proceed as if the first argument after -- was command. Possible values: ant, buck1, buck, buck2, gradle, gradlew, java, javac, @@ -174,93 +174,91 @@

    OPTIONS mvn, mvnw, ndk-build, python3, rebar3, erlc, xcodebuild.

    -

    --help

    +

    --help

    -

    Show this manual

    +

    Show this manual

    -

    --help-format { auto -| groff | pager | plain }

    +

    --help-format { auto | +groff | pager | plain }

    -

    Show this help in the specified +

    Show this help in the specified format. auto sets the format to plain if the environment variable TERM is "dumb" or undefined, and to pager otherwise.

    -

    --help-full

    +

    --help-full

    -

    Show this manual with all +

    Show this manual with all internal options in the INTERNAL OPTIONS section

    -

    --never-returning-null +

    --never-returning-null json

    -

    [Java only, all analyses] +

    [Java only, all analyses] Matcher or list of matchers for functions that never return null.

    -

    --pmd-xml

    +

    --pmd-xml

    -

    Activates: Output issues in +

    Activates: Output issues in (PMD) XML format in infer-out/report.xml (Conversely: --no-pmd-xml)

    -

    --print-logs

    +

    --print-logs

    -

    Activates: Also log messages to +

    Activates: Also log messages to stdout and stderr (Conversely: --no-print-logs)

    -

    --no-progress-bar,-P

    +

    --no-progress-bar,-P

    -

    Deactivates: Show a progress +

    Deactivates: Show a progress bar (Conversely: --progress-bar | -p)

    - -

    --project-root,-C +

    --project-root,-C dir

    -

    Specify the root directory of +

    Specify the root directory of the project

    -

    --no-report

    +

    --no-report

    -

    Deactivates: Run the reporting +

    Deactivates: Run the reporting phase once the analysis has completed (Conversely: --report)

    -

    --report-allow-list-path-regex +

    --report-allow-list-path-regex +path_regex

    -

    Report issues only on files +

    Report issues only on files whose relative path matches the specified OCaml regex (and which do not match --report-block-list-path-regex)

    -

    --report-block-list-files-containing +

    --report-block-list-files-containing +string

    -

    Do not report any issues on +

    Do not report any issues on files containing the specified string

    -

    --report-block-list-path-regex +

    --report-block-list-path-regex +path_regex

    -

    Do not report any issues on +

    Do not report any issues on files whose relative path matches the specified OCaml regex, even if they match the allow list specified by --report-allow-list-path-regex

    - -

    --report-block-list-spec +

    --report-block-list-spec json

    -

    Do not report the issues in +

    Do not report the issues in this list.

    -

    Example format:
    +

    Example format:
    "report-block-list-spec": [
    { "bug_type": "CXX_REF_CAPTURED_IN_BLOCK",
    @@ -277,94 +275,93 @@

    OPTIONS ]
    --report-force-relative-path

    -

    Activates: Force converting an +

    Activates: Force converting an absolute path to a relative path to the root directory (Conversely: --no-report-force-relative-path)

    - -

    --report-suppress-errors +

    --report-suppress-errors +error_name

    -

    do not report a type of +

    do not report a type of errors

    -

    --results-dir,-o +

    --results-dir,-o dir

    -

    Write results and internal +

    Write results and internal files in the specified directory

    -

    --sarif

    +

    --sarif

    -

    Activates: Output issues in +

    Activates: Output issues in SARIF (Static Analysis Results Interchange Format) in infer-out/report.sarif (Conversely: --no-sarif)

    -

    --skip-analysis-in-path +

    --skip-analysis-in-path +regex

    -

    Ignore files whose path matches +

    Ignore files whose path matches a given regex (can be specified multiple times, but you must make sure each regex is properly bracketed)

    -

    --sqlite-cache-size +

    --sqlite-cache-size int

    -

    SQLite cache size in pages (if +

    SQLite cache size in pages (if positive) or kB (if negative), follows formal of corresponding SQLite PRAGMA.

    -

    --sqlite-lock-timeout +

    --sqlite-lock-timeout int

    -

    Timeout for SQLite results +

    Timeout for SQLite results database operations, in milliseconds.

    -

    --sqlite-max-blob-size +

    --sqlite-max-blob-size int

    -

    Maximum blob/string size for +

    Maximum blob/string size for data written in SQLite.

    -

    --sqlite-mmap-size +

    --sqlite-mmap-size int

    -

    Size of memory map for mmaped +

    Size of memory map for mmaped SQLite databases, zero value disables memory mapping.

    -

    --sqlite-page-size +

    --sqlite-page-size int

    -

    SQLite page size in bytes, must +

    SQLite page size in bytes, must be a power of two between 512 and 65536.

    -

    --timeout +

    --timeout float

    -

    Time after which any checker +

    Time after which any checker (except biabduction) should give up analysing the current function or method, in seconds

    -

    --version

    +

    --version

    -

    Print version information and +

    Print version information and exit

    -

    --version-json

    +

    --version-json

    -

    Print version information in +

    Print version information in json format and exit

    - + - - +

    --

    +

    Stop argument processing, use remaining arguments as a @@ -377,32 +374,32 @@

    BUCK OPTIONS -

    --buck-block-list +

    --buck-block-list +regex

    -

    Skip capture of files matched +

    Skip capture of files matched by the specified regular expression. Only the clang, non-compilation-database

    -

    Buck integration is supported, +

    Buck integration is supported, not Java.
    --buck-targets-block-list
    +regex

    -

    Skip capture of buck targets +

    Skip capture of buck targets matched by the specified regular expression.

    -

    --buck2-bxl-capture-file-block-list +

    --buck2-bxl-capture-file-block-list +regex

    -

    Skip capture of files matched +

    Skip capture of files matched by the specified regular expression. Only the clang, Buck2 integration is supported, not Java.

    -

    --buck2-root +

    --buck2-root dir

    -

    Specify the parent directory of +

    Specify the parent directory of buck-out (used only for buck2).

    ENVIRONMENT @@ -411,10 +408,10 @@

    ENVIRONMENT -

    INFER_ARGS, +

    INFER_ARGS, INFERCONFIG, INFER_STRICT_MODE

    -

    See the ENVIRONMENT section in +

    See the ENVIRONMENT section in the manual of infer(1).

    FILES @@ -423,9 +420,9 @@

    FILES -

    .inferconfig

    +

    .inferconfig

    -

    See the FILES section in the +

    See the FILES section in the manual of infer(1).

    SEE ALSO @@ -434,7 +431,7 @@

    SEE ALSO -

    infer-analyze(1), +

    infer-analyze(1), infer-capture(1), infer-report(1)


    diff --git a/man/next/infer.1.html b/man/next/infer.1.html index 1c97382b8be..49c2b088f00 100644 --- a/man/next/infer.1.html +++ b/man/next/infer.1.html @@ -1,4 +1,4 @@ - + @@ -35,7 +35,7 @@

    NAME

    -

    infer - static +

    infer - static analysis for Java and C/C++/Objective-C/Objective-C++

    SYNOPSIS @@ -43,7 +43,7 @@

    SYNOPSIS

    -

    infer +

    infer analyze [options]
    infer capture
    [options]
    infer compile
    [options]
    @@ -62,19 +62,19 @@

    DESCRIPTION

    -

    Infer is a +

    Infer is a static analyzer. Given a collection of source files written in Java or in languages of the C family, and a command to build them, infer produces a list of potential issues.

    -

    Infer consists +

    Infer consists of a collection of tools referenced in the SEE ALSO section of this manual. See their respective manuals for more information.

    -

    When run -without a subcommand, and if a compilation command is -specified via the -- option or one of the +

    When run without +a subcommand, and if a compilation command is specified via +the -- option or one of the --clang-compilation-database[-escaped] options, then infer behaves as infer-run(1). Otherwise, infer behaves as infer-analyze(1).

    @@ -84,12 +84,12 @@

    OPTIONS

    -

    Every infer +

    Every infer command accepts the arguments from all the other infer commands.

    -

    Options are -read from the .inferconfig file, then from the +

    Options are read +from the .inferconfig file, then from the INFER_ARGS environment variable, then from the command line. Options in INFER_ARGS take precedence over options in .inferconfig, and options passed on @@ -98,13 +98,13 @@

    OPTIONS FILES sections of this manual for more information.

    -

    Options can be +

    Options can be specified inside an argument file file by passing @file as argument. The format is one option per line, and enclosing single ' and double " quotes are ignored.

    -

    Options without +

    Options without a default value (e.g., --changed-files-index) and options with list-like values (e.g., --Xbuck) all have a corresponding --option-reset flag that resets @@ -112,22 +112,22 @@

    OPTIONS instance, --Xbuck-reset will cancel any previous --Xbuck option passed to infer.

    -

    See the manuals +

    See the manuals of individual infer commands for details about their supported options. The following is a list of all the supported options (see also --help-full for options reserved for internal use).
    --analysis-schedule-file
    path

    -

    The file where an analysis +

    The file where an analysis schedule is stored. The default is infer-out/analysis_dependency_graph

    -

    See also +

    See also infer-analyze(1).
    --annotation-reachability

    -

    Activates: +

    Activates: annotation-reachability checker: Given pairs of source and sink annotations, e.g. ‘@A‘ and ‘@B‘, this checker will warn whenever some @@ -143,44 +143,44 @@

    OPTIONS with ‘--annotation-reachability‘. (Conversely: --no-annotation-reachability)

    -

    See also +

    See also infer-analyze(1).
    --no-annotation-reachability-apply-superclass-annotations

    -

    Deactivates: Applies +

    Deactivates: Applies annotations from superclasses and interfaces also on methods that are not overridden from the superclass or interface. (Conversely: --annotation-reachability-apply-superclass-annotations)

    -

    See also +

    See also infer-analyze(1).
    --annotation-reachability-check-loops

    -

    Activates: Highlights callsites +

    Activates: Highlights callsites in the trace that are nested in some loop. (Conversely: --no-annotation-reachability-check-loops)

    -

    See also +

    See also infer-analyze(1).
    --annotation-reachability-custom-models
    json

    -

    Specify a map from annotations +

    Specify a map from annotations to lists of regexps to treat matching methods as if they had the annotation.

    -

    Example format: +

    Example format: {"Annotation": ["com\\.Myclass\\.foo.*"]}
    See also infer-analyze(1).
    --annotation-reachability-custom-pairs
    json

    -

    Specify custom sources/sinks, +

    Specify custom sources/sinks, and optionally sanitizers for the annotation reachability checker

    -

    Example format: for custom +

    Example format: for custom annotations
    com.my.annotation.{Source1,Source2,Sink1,Sanitizer1}
    { "sources" : ["Source1", @@ -190,368 +190,368 @@

    OPTIONS See also infer-analyze(1).
    --annotation-reachability-expensive

    -

    Activates: check if methods +

    Activates: check if methods annotated with @PerformanceCritical can call expensive methods (annotated @Expensive or modeled, with annotation reachability checker) (Conversely: --no-annotation-reachability-expensive)

    -

    See also +

    See also infer-analyze(1).
    --no-annotation-reachability-minimize-sinks

    -

    Deactivates: do not report +

    Deactivates: do not report paths where a prefix is also a source to sink path. For example if there is a source() -> sink1() -> sink2() path then only source() -> sink1() will be reported. (Conversely: --annotation-reachability-minimize-sinks)

    -

    See also +

    See also infer-analyze(1).
    --annotation-reachability-minimize-sources

    -

    Activates: do not report paths +

    Activates: do not report paths where a suffix is also a source to sink path. For example if there is a source1() -> source2() -> sink() path then only source2() -> sink() will be reported. (Conversely: --no-annotation-reachability-minimize-sources)

    -

    See also +

    See also infer-analyze(1).
    --annotation-reachability-no-allocation

    -

    Activates: check if methods +

    Activates: check if methods annotated with @NoAllocation can allocate (with annotation reachability checker) (Conversely: --no-annotation-reachability-no-allocation)

    -

    See also +

    See also infer-analyze(1).
    --annotation-reachability-only

    -

    Activates: Enable +

    Activates: Enable annotation-reachability and disable all other checkers (Conversely: --no-annotation-reachability-only)

    -

    See also +

    See also infer-analyze(1).
    --annotation-reachability-report-source-and-sink

    -

    Activates: Reports methods that +

    Activates: Reports methods that are marked as both a source and a sink at the same time. (Conversely: --no-annotation-reachability-report-source-and-sink)

    -

    See also +

    See also infer-analyze(1).
    --append-buck-flavors
    +string

    -

    Additional Buck flavors to +

    Additional Buck flavors to append to targets discovered by the --buck-compilation-database option.

    -

    See also +

    See also infer-capture(1).
    --biabduction

    -

    Activates: biabduction +

    Activates: biabduction checker: This analysis deals with a range of issues, many linked to memory safety.

    -

    DEPRECATED: This has -been replaced by Pulse and will be removed
    +

    DEPRECATED: This has been +replaced by Pulse and will be removed
    in the next release.
    (Conversely: --no-biabduction)
    See also infer-analyze(1).
    --biabduction-only

    -

    Activates: Enable +

    Activates: Enable biabduction and disable all other checkers (Conversely: --no-biabduction-only)

    -

    See also +

    See also infer-analyze(1).
    --biabduction-unsafe-malloc

    -

    Activates: Assume that +

    Activates: Assume that malloc(3) never returns null. (Conversely: --no-biabduction-unsafe-malloc)

    -

    See also +

    See also infer-analyze(1).
    --biabduction-write-dotty

    -

    Activates: Produce dotty files +

    Activates: Produce dotty files for specs and retain cycles reports in infer-out/captured. (Conversely: --no-biabduction-write-dotty)

    -

    See also +

    See also infer-analyze(1).
    --no-bo-assume-void

    -

    Deactivates: Assume void type +

    Deactivates: Assume void type as a type of record fields not in type environment. (Conversely: --bo-assume-void)

    -

    See also +

    See also infer-analyze(1).
    --no-bo-bottom-as-default

    -

    Deactivates: Use bottom as a +

    Deactivates: Use bottom as a default value instead of unknown. (Conversely: --bo-bottom-as-default)

    -

    See also +

    See also infer-analyze(1).
    --bo-context-sensitive-allocsites

    -

    Activates: Assume that +

    Activates: Assume that different calls to the same function creating an allocsite results in different allocsites imported to the caller. (Conversely: --no-bo-context-sensitive-allocsites)

    -

    See also +

    See also infer-analyze(1).
    --bo-debug
    int

    -

    Debug level for buffer-overrun +

    Debug level for buffer-overrun checker (0-4)

    -

    See also +

    See also infer-analyze(1).
    --bo-exit-frontend-gener-vars

    -

    Activates: Put frontend +

    Activates: Put frontend generated variables out of scope when they are listed in exit scope instruction. (Conversely: --no-bo-exit-frontend-gener-vars)

    -

    See also +

    See also infer-analyze(1).
    --bo-field-depth-limit
    int

    -

    Limit of field depth of +

    Limit of field depth of abstract location in buffer-overrun checker

    -

    See also +

    See also infer-analyze(1).
    --bo-max-cfg-size
    int

    -

    Larger CFGs than the max size +

    Larger CFGs than the max size are skipped in buffer overrun analysis.

    -

    See also +

    See also infer-analyze(1).
    --bo-sound-unknown-sets-join

    -

    Activates: Join with an unknown +

    Activates: Join with an unknown set always result in an unknown set. When disabled, unknown set behaves as bot. (Conversely: --no-bo-sound-unknown-sets-join)

    -

    See also +

    See also infer-analyze(1).
    --bootclasspath
    string

    -

    Specify the Java +

    Specify the Java bootclasspath

    -

    See also +

    See also infer-capture(1).
    --buck-block-list
    +regex

    -

    Skip capture of files matched +

    Skip capture of files matched by the specified regular expression. Only the clang, non-compilation-database

    -

    Buck integration is supported, +

    Buck integration is supported, not Java.
    See also infer-capture(1) and infer-run(1).
    --buck-clang

    -

    Activates: Buck integration for +

    Activates: Buck integration for clang-based targets (C/C++/Objective-C/Objective-C++). (Conversely: --no-buck-clang)

    -

    See also +

    See also infer-capture(1).
    --buck-clang-use-toolchain-config

    -

    Activates: Suppress setting +

    Activates: Suppress setting buck config values for the infer binary and other values in the buck-clang-flavor integration and instead rely on buck toolchain configuration options. (Conversely: --no-buck-clang-use-toolchain-config)

    -

    See also +

    See also infer-capture(1).
    --buck-compilation-database
    { no-deps | deps }

    -

    Buck integration using the +

    Buck integration using the compilation database, with or without dependencies. Only includes clang targets, as per Buck's #compilation-database flavor.

    -

    See also +

    See also infer-capture(1).
    --buck-compilation-database-depth
    int

    -

    Depth of dependencies used by +

    Depth of dependencies used by the --buck-compilation-database deps option. By default, all recursive dependencies are captured.

    -

    See also +

    See also infer-capture(1).
    --buck-dependency-depth
    int

    -

    Capture dependencies only if +

    Capture dependencies only if they are at most the depth provided, or all transitive dependencies if depth is not provided (the default). In particular, depth zero means capture exactly the targets provided and nothing else.

    -

    See also +

    See also infer-capture(1).
    --buck-erlang

    -

    Activates: Buck integration for +

    Activates: Buck integration for Erlang. (Conversely: --no-buck-erlang)

    -

    See also +

    See also infer-capture(1).
    --buck-java

    -

    Activates: Buck integration for +

    Activates: Buck integration for Java. (Conversely: --no-buck-java)

    -

    See also +

    See also infer-capture(1).
    --buck-java-heap-size-gb
    int

    -

    Explicitly set the size of the +

    Explicitly set the size of the Java heap of Buck processes, in gigabytes.

    -

    See also +

    See also infer-capture(1).
    --buck-java-suppress-config

    -

    Activates: Suppress setting +

    Activates: Suppress setting buck config values for the infer binary and its version in the buck-java integration. (Conversely: --no-buck-java-suppress-config)

    -

    See also +

    See also infer-capture(1).
    --buck-merge-all-deps

    -

    Activates: Find and merge all +

    Activates: Find and merge all infer dependencies produced by buck. Use this flag if infer doesn't find any files to analyze after a successful capture. Only valid for --buck-clang. (Conversely: --no-buck-merge-all-deps)

    -

    See also +

    See also infer-capture(1).
    --buck-targets-block-list
    +regex

    -

    Skip capture of buck targets +

    Skip capture of buck targets matched by the specified regular expression.

    -

    See also -infer-capture(1) and infer-run(1).
    +

    See also infer-capture(1) +and infer-run(1).
    --buck2-bxl-capture-file-block-list
    +regex

    -

    Skip capture of files matched +

    Skip capture of files matched by the specified regular expression. Only the clang, Buck2 integration is supported, not Java.

    -

    See also -infer-capture(1) and infer-run(1).
    +

    See also infer-capture(1) +and infer-run(1).
    --buck2-bxl-target
    string

    -

    Buck2 BXL script (as a buck +

    Buck2 BXL script (as a buck target) to run when capturing with buck2/clang integration.

    -

    See also +

    See also infer-capture(1).
    --buck2-inferconfig-target
    string

    -

    Buck2 target representing the +

    Buck2 target representing the inferconfig file; used in BXL capture.

    -

    See also +

    See also infer-capture(1).
    --buck2-infertoolchain-target
    string

    -

    Buck2 target representing the +

    Buck2 target representing the infer toolchain; used in BXL capture.

    -

    See also +

    See also infer-capture(1).
    --buck2-isolation-dir
    string

    -

    Run buck bxl capture with the +

    Run buck bxl capture with the given isolation directory as parameter.

    -

    See also +

    See also infer-capture(1).
    --no-buck2-query-deps

    -

    Deactivates: Query deps of +

    Deactivates: Query deps of given targets and run capture on the result (alternatively run capture on given targets) (Conversely: --buck2-query-deps)

    -

    See also +

    See also infer-capture(1).
    --buck2-root
    dir

    -

    Specify the parent directory of +

    Specify the parent directory of buck-out (used only for buck2).

    -

    See also -infer-capture(1) and infer-run(1).
    +

    See also infer-capture(1) +and infer-run(1).
    --bufferoverrun

    -

    Activates: bufferoverrun +

    Activates: bufferoverrun checker: InferBO is a detector for out-of-bounds array accesses. (Conversely: --no-bufferoverrun)

    -

    See also +

    See also infer-analyze(1).
    --bufferoverrun-only

    -

    Activates: Enable +

    Activates: Enable bufferoverrun and disable all other checkers (Conversely: --no-bufferoverrun-only)

    -

    See also +

    See also infer-analyze(1).
    --capture-block-list
    json

    -

    Matcher or list of matchers for +

    Matcher or list of matchers for names of files that should not be captured, hence not analyzed either. Clang, Java, and Hack only.

    -

    See also -infer-capture(1) and infer-run(1).
    +

    See also infer-capture(1) +and infer-run(1).
    --no-censor-report
    +issue_type_regex

    -

    For debugging/experimentation +

    For debugging/experimentation only: Specify issues not to be censored by --censor-report.

    -

    See also infer-report(1) +

    See also infer-report(1) and infer-run(1).
    --censor-report
    +string

    -

    Specify a filter for issues to +

    Specify a filter for issues to be censored by adding a 'censored_reason' field in the json report. Infer will not report censored issues on the console output and in report.txt, but tools that post-process the @@ -574,79 +574,79 @@

    OPTIONS ‘<reason_string>‘ is a non-empty string used to explain why the issue was filtered.

    -

    See also infer-report(1) +

    See also infer-report(1) and infer-run(1).
    --cfg-json
    file

    -

    Path to CFG json file

    +

    Path to CFG json file

    -

    See also +

    See also infer-capture(1).
    --changed-files-index
    file

    -

    Specify the file containing the +

    Specify the file containing the list of source files from which reactive analysis should start. Source files should be specified relative to project root or be absolute

    -

    See also +

    See also infer-analyze(1).
    --clang-biniou-file
    file

    -

    Specify a file containing the +

    Specify a file containing the AST of the program, in biniou format. Please note you still need to provide a compilation command.

    -

    See also +

    See also infer-capture(1).
    --clang-block-listed-flags
    +string

    -

    Clang flags to filter out

    +

    Clang flags to filter out

    -

    See also +

    See also infer-capture(1).
    --clang-block-listed-flags-with-arg
    +string

    -

    Clang flags (taking args) to +

    Clang flags (taking args) to filter out

    -

    See also +

    See also infer-capture(1).
    --clang-compound-literal-init-limit
    int

    -

    Limit after which +

    Limit after which initialization of compound types (structs and arrays) is not done element by element but using a builtin function that each analysis has to model.

    -

    See also -infer-analyze(1) and infer-capture(1).
    +

    See also infer-analyze(1) +and infer-capture(1).
    --clang-yojson-file
    file

    -

    Specify a file containing the +

    Specify a file containing the AST of the program, in yojson format. Please note you still need to provide a compilation command.

    -

    See also +

    See also infer-capture(1).
    --compilation-database
    +path

    -

    File that contain compilation +

    File that contain compilation commands (can be specified multiple times)

    -

    See also +

    See also infer-capture(1).
    --compilation-database-escaped
    +path

    -

    File that contain compilation +

    File that contain compilation commands where all entries are escaped for the shell, eg coming from Xcode (can be specified multiple times)

    -

    See also +

    See also infer-capture(1).
    --complete-capture-from
    path

    -

    Provide the path to an infer +

    Provide the path to an infer results directory containing a capture database. The capture database specified with --results-dir) (which must exist) will be completed from the input database and @@ -654,147 +654,147 @@

    OPTIONS directory. The exit code will be equal to the number of rows added to the capture database.

    -

    See also infer-debug(1). +

    See also infer-debug(1).
    --config-impact-analysis

    -

    Activates: +

    Activates: config-impact-analysis checker: [EXPERIMENTAL] Collects function that are called without config checks. (Conversely: --no-config-impact-analysis)

    -

    See also +

    See also infer-analyze(1).
    --config-impact-analysis-only

    -

    Activates: Enable +

    Activates: Enable config-impact-analysis and disable all other checkers (Conversely: --no-config-impact-analysis-only)

    -

    See also +

    See also infer-analyze(1).
    --config-impact-current
    path

    -

    Config impact report of the +

    Config impact report of the latest revision

    -

    See also +

    See also infer-reportdiff(1).
    --config-impact-data-file
    file

    -

    [ConfigImpact] Specify the file +

    [ConfigImpact] Specify the file containing the config data

    -

    See also -infer-report(1).
    +

    See also infer-report(1). +
    --config-impact-issues-tests
    file

    -

    Write a list of config impact +

    Write a list of config impact issues in a format suitable for config impact tests to file

    -

    See also -infer-report(1).
    +

    See also infer-report(1). +
    --config-impact-max-callees-to-print
    int

    -

    Specify the maximum number of +

    Specify the maximum number of unchecked callees to print in the config impact checker

    -

    See also infer-report(1) +

    See also infer-report(1) and infer-reportdiff(1).
    --config-impact-previous
    path

    -

    Config impact report of the +

    Config impact report of the base revision to use for comparison

    -

    See also +

    See also infer-reportdiff(1).
    --continue

    -

    Activates: Continue the capture +

    Activates: Continue the capture for the reactive analysis, increasing the changed files/procedures. (If a procedure was changed beforehand, keep the changed marking.) (Conversely: --no-continue)

    -

    See also +

    See also infer-capture(1).
    --continue-analysis

    -

    Activates: Continue the +

    Activates: Continue the analysis after more targets are captured by --continue. The other analysis options should be given the same before. Not compatible with --reanalyze and --incremental-analysis. (Conversely: --no-continue-analysis)

    -

    See also +

    See also infer-analyze(1).
    --cost

    -

    Activates: cost checker: +

    Activates: cost checker: Computes the asymptotic complexity of functions with respect to execution cost or other user defined resources. Can be used to detect changes in the complexity with ‘infer reportdiff‘. (Conversely: --no-cost)

    -

    See also +

    See also infer-analyze(1).
    --cost-issues-tests
    file

    -

    Write a list of cost issues in +

    Write a list of cost issues in a format suitable for cost tests to file

    -

    See also -infer-report(1).
    +

    See also infer-report(1). +
    --cost-only

    -

    Activates: Enable cost +

    Activates: Enable cost and disable all other checkers (Conversely: --no-cost-only)

    -

    See also +

    See also infer-analyze(1).
    --no-cost-suppress-func-ptr

    -

    Deactivates: Suppress printing +

    Deactivates: Suppress printing function pointers in cost reports (Conversely: --cost-suppress-func-ptr)

    -

    See also +

    See also infer-analyze(1).
    --costs-current
    path

    -

    Costs report of the latest +

    Costs report of the latest revision

    -

    See also +

    See also infer-reportdiff(1).
    --costs-previous
    path

    -

    Costs report of the base +

    Costs report of the base revision to use for comparison

    -

    See also +

    See also infer-reportdiff(1).
    --no-cxx

    -

    Deactivates: Analyze C++ +

    Deactivates: Analyze C++ methods (Conversely: --cxx)

    -

    See also +

    See also infer-capture(1).
    --cxx-scope-guards
    json

    -

    Specify scope guard classes +

    Specify scope guard classes that can be read only by destructors without being reported as dead stores.

    -

    See also +

    See also infer-analyze(1).
    --debug
    ,-g

    -

    Activates: Debug mode (also +

    Activates: Debug mode (also sets --debug-level 2, --developer-mode, --print-buckets, --print-types, --reports-include-ml-loc, @@ -802,19 +802,19 @@

    OPTIONS --write-html) (Conversely: --no-debug | -G)

    -

    See also +

    See also infer-analyze(1), infer-capture(1), infer-compile(1),
    infer-report
    (1), infer-reportdiff(1), and infer-run(1).
    --debug-level
    level

    -

    Debug level (sets +

    Debug level (sets --bo-debug level, --debug-level-analysis level, --debug-level-capture level):

    -

    - 0: only basic debugging +

    - 0: only basic debugging enabled
    - 1: verbose debugging enabled
    - 2: very verbose debugging enabled
    @@ -824,46 +824,46 @@

    OPTIONS infer-run(1).
    --debug-level-analysis
    int

    -

    Debug level for the analysis. +

    Debug level for the analysis. See --debug-level for accepted values.

    -

    See also +

    See also infer-analyze(1), infer-capture(1), infer-compile(1),
    infer-report
    (1), infer-reportdiff(1), and infer-run(1).
    --debug-level-capture
    int

    -

    Debug level for the capture. +

    Debug level for the capture. See --debug-level for accepted values.

    -

    See also +

    See also infer-analyze(1), infer-capture(1), infer-compile(1),
    infer-report
    (1), infer-reportdiff(1), and infer-run(1).
    --debug-level-report
    int

    -

    Debug level for the report. See +

    Debug level for the report. See --debug-level for accepted values.

    -

    See also +

    See also infer-analyze(1), infer-capture(1), infer-compile(1),
    infer-report
    (1), infer-reportdiff(1), and infer-run(1).
    --no-deduplicate

    -

    Deactivates: Apply +

    Deactivates: Apply issue-specific deduplication during analysis and/or reporting. (Conversely: --deduplicate)

    -

    See also +

    See also infer-analyze(1), infer-report(1), and
    infer-reportdiff
    (1).
    --no-default-checkers

    -

    Deactivates: Default checkers: +

    Deactivates: Default checkers: --static-constructor-stall-checker, --fragment-retains-view, --inefficient-keyset-iterator, --liveness, @@ -872,20 +872,20 @@

    OPTIONS --starvation (Conversely: --default-checkers)

    -

    See also +

    See also infer-analyze(1).
    --dependencies

    -

    Activates: Translate all the +

    Activates: Translate all the dependencies during the capture. The classes in the given jar file will be translated. No sources needed. (Conversely: --no-dependencies)

    -

    See also +

    See also infer-capture(1).
    --detach-analysis-dependency

    -

    Activates: Detach analysis +

    Activates: Detach analysis dependencies of checkers during the analysis, so that each checker triggers themselves only when analyzing a callee. This can save unnecessary analyses on the situation that NOT @@ -893,34 +893,34 @@

    OPTIONS --changed-files-index is given. (Conversely: --no-detach-analysis-dependency)

    -

    See also +

    See also infer-analyze(1).
    --dict-missing-key-var-block-list
    +string

    -

    Skip analyzing the variables in +

    Skip analyzing the variables in the dict-missing-key checker.

    -

    See also +

    See also infer-analyze(1).
    --differential-filter-files
    string

    -

    Specify the file containing the +

    Specify the file containing the list of source files for which a differential report is desired. Source files should be specified relative to project root or be absolute

    -

    See also -infer-report(1).
    +

    See also infer-report(1). +
    --disable-issue-type
    +issue_type

    -

    Do not show reports coming from +

    Do not show reports coming from this type of issue. Each checker can report a range of issue types. This option provides fine-grained filtering over which types of issue should be reported once the checkers have run. In particular, note that disabling issue types does not make the corresponding checker not run.

    -

    Available issue types are as +

    Available issue types are as follows:
    ARBITRARY_CODE_EXECUTION_UNDER_LOCK (enabled by default),
    @@ -1004,6 +1004,7 @@

    OPTIONS INFERBO_ALLOC_MAY_BE_BIG (enabled by default),
    INFERBO_ALLOC_MAY_BE_NEGATIVE (enabled by default),
    INFINITE_EXECUTION_TIME (disabled by default),
    +INFINITE_RECURSION (disabled by default),
    INHERENTLY_DANGEROUS_FUNCTION (enabled by default),
    INTEGER_OVERFLOW_L1 (enabled by default),
    INTEGER_OVERFLOW_L2 (enabled by default),
    @@ -1018,6 +1019,7 @@

    OPTIONS LINEAGE_FLOW (enabled by default),
    LOCKLESS_VIOLATION (enabled by default),
    LOCK_CONSISTENCY_VIOLATION (enabled by default),
    +LOCK_ON_UI_THREAD (disabled by default),
    Leak_after_array_abstraction (enabled by default),
    Leak_in_footprint (enabled by default),
    Leak_unknown_origin (disabled by default),
    @@ -1133,150 +1135,150 @@

    OPTIONS See also infer-report(1).
    --dump-duplicate-symbols

    -

    Activates: Dump all symbols +

    Activates: Dump all symbols with the same name that are defined in more than one file. (Conversely: --no-dump-duplicate-symbols)

    -

    See also +

    See also infer-capture(1).
    --dynamic-dispatch-json-file-path
    path

    -

    Dynamic dispatch file path to +

    Dynamic dispatch file path to get the JSON used for method name substitution

    -

    See also +

    See also infer-analyze(1).
    --enable-issue-type
    +issue_type

    -

    Show reports coming from this +

    Show reports coming from this type of issue. By default, all issue types are enabled except the ones listed in --disable-issue-type. Note that enabling issue types does not make the corresponding checker run; see individual checker options to turn them on or off.

    -

    See also -infer-report(1).
    +

    See also infer-report(1). +
    --erlang-ast-dir
    dir

    -

    Also load AST from all .json +

    Also load AST from all .json files in the given path. These .json files usually come from a previous run with --debug.

    -

    See also +

    See also infer-capture(1).
    --erlang-check-return

    -

    Activates: Check whether the +

    Activates: Check whether the values returned by functions correspond to what the function's spec promises. This check is introduced at capture time. (Conversely: --no-erlang-check-return)

    -

    See also +

    See also infer-capture(1).
    --erlang-list-unfold-depth
    int

    -

    Unfold Erlang lists up to depth +

    Unfold Erlang lists up to depth int

    -

    See also +

    See also infer-analyze(1).
    --no-erlang-reliability

    -

    Deactivates: Analyze crashing +

    Deactivates: Analyze crashing executions. This flag affects both capture and analysis. At capture time, it encodes Erlang specs; at (Pulse) analysis time, it models Erlang exceptions (builtin or OTP ones). (Conversely: --erlang-reliability)

    -

    See also -infer-analyze(1) and infer-capture(1).
    +

    See also infer-analyze(1) +and infer-capture(1).
    --erlang-skip-compile

    -

    Activates: Skip running +

    Activates: Skip running compiler (erlc/rebar3), to save time. The build command is basically ignored in this case. To be used together with --erlang-ast-dir. (Conversely: --no-erlang-skip-compile)

    -

    See also +

    See also infer-capture(1).
    --erlang-with-otp-specs

    -

    Activates: [EXPERIMENTAL] Use +

    Activates: [EXPERIMENTAL] Use type specs from OTP (available in the system) to generate more precise Pulse summaries for unknown library functions. (Conversely: --no-erlang-with-otp-specs)

    -

    See also +

    See also infer-capture(1).
    --external-java-packages
    +prefix

    -

    Specify a list of Java package +

    Specify a list of Java package prefixes for external Java packages. If set, the analysis will not report non-actionable warnings on those packages.

    -

    See also +

    See also infer-analyze(1).
    --extract-capture-from
    path

    -

    Provide the path to an infer +

    Provide the path to an infer results directory containing a capture database. Together with a list of files provided through the obligatory use of --changed-files-index, create a new capture database containing only the artefacts related to these files (in the location specified with --results-dir).

    -

    See also infer-debug(1). +

    See also infer-debug(1).
    --fail-on-issue

    -

    Activates: Exit with error code +

    Activates: Exit with error code 2 if Infer found something to report (Conversely: --no-fail-on-issue)

    -

    See also infer-run(1). +

    See also infer-run(1).
    --file-renamings
    path

    -

    JSON with a list of file +

    JSON with a list of file renamings to use while computing differential reports

    -

    See also +

    See also infer-reportdiff(1).
    --files-to-analyze-index
    file

    -

    File containing a list of +

    File containing a list of source files where analysis should start from. When used, the set of files given to this argument must be a subset of that passed to --changed-files-index (which must be specified).

    -

    See also +

    See also infer-analyze(1).
    --no-filtering
    ,-F

    -

    Deactivates: Do not show the +

    Deactivates: Do not show the experimental and block listed issue types (Conversely: --filtering | -f)

    -

    See also -infer-report(1).
    +

    See also infer-report(1). +
    --force-delete-results-dir

    -

    Activates: Do not refuse to +

    Activates: Do not refuse to delete the results directory if it doesn't look like an infer results directory. (Conversely: --no-force-delete-results-dir)

    -

    See also +

    See also infer-capture(1), infer-compile(1), and infer-run(1).
    --force-integration
    command

    -

    Proceed as if the first +

    Proceed as if the first argument after -- was command. Possible values: ant, buck1, buck, buck2, gradle, gradlew, java, javac, @@ -1286,84 +1288,84 @@

    OPTIONS mvn, mvnw, ndk-build, python3, rebar3, erlc, xcodebuild.

    -

    See also -infer-capture(1) and infer-run(1).
    +

    See also infer-capture(1) +and infer-run(1).
    --no-fragment-retains-view

    -

    Deactivates: +

    Deactivates: fragment-retains-view checker: Detects when Android fragments are not explicitly nullified before becoming unreachable. (Conversely: --fragment-retains-view)

    -

    See also +

    See also infer-analyze(1).
    --fragment-retains-view-only

    -

    Activates: Enable +

    Activates: Enable fragment-retains-view and disable all other checkers (Conversely: --no-fragment-retains-view-only)

    -

    See also +

    See also infer-analyze(1).
    --from-json-config-impact-report
    config-impact-report.json

    -

    Load costs analysis results +

    Load costs analysis results from a config-impact-report file.

    -

    See also -infer-report(1).
    +

    See also infer-report(1). +
    --from-json-costs-report
    costs-report.json

    -

    Load costs analysis results +

    Load costs analysis results from a costs-report file.

    -

    See also -infer-report(1).
    +

    See also infer-report(1). +
    --from-json-report
    report.json

    -

    Load analysis results from a +

    Load analysis results from a report file (default is to load the results from the specs files generated by the analysis).

    -

    See also -infer-report(1).
    +

    See also infer-report(1). +
    --frontend-tests

    -

    Activates: Save +

    Activates: Save filename.ext.test.dot with the cfg in dotty format for frontend tests (also sets --print-types) (Conversely: --no-frontend-tests)

    -

    See also +

    See also infer-capture(1).
    --generated-classes
    path

    -

    Specify where to load the +

    Specify where to load the generated class files

    -

    See also +

    See also infer-capture(1).
    --global-tenv

    -

    Activates: Print the global +

    Activates: Print the global type environment. (Conversely: --no-global-tenv)

    -

    See also infer-debug(1). +

    See also infer-debug(1).
    --headers

    -

    Activates: Analyze code in +

    Activates: Analyze code in header files (Conversely: --no-headers)

    -

    See also +

    See also infer-capture(1).
    --help

    -

    Show this manual

    +

    Show this manual

    -

    See also +

    See also infer-analyze(1), infer-capture(1), infer-compile(1),
    infer-debug
    (1), infer-explore(1), @@ -1371,21 +1373,21 @@

    OPTIONS infer-reportdiff(1), and infer-run(1).
    --help-checker
    +checker-id

    -

    Show information about a +

    Show information about a checker, for example biabduction. To see the list of all checkers, see --list-checkers.

    -

    See also infer-help(1). +

    See also infer-help(1).
    --help-format
    { auto | groff | pager | plain }

    -

    Show this help in the specified +

    Show this help in the specified format. auto sets the format to plain if the environment variable TERM is "dumb" or undefined, and to pager otherwise.

    -

    See also +

    See also infer-analyze(1), infer-capture(1), infer-compile(1),
    infer-debug
    (1), infer-explore(1), @@ -1393,10 +1395,10 @@

    OPTIONS infer-reportdiff(1), and infer-run(1).
    --help-full

    -

    Show this manual with all +

    Show this manual with all internal options in the INTERNAL OPTIONS section

    -

    See also +

    See also infer-analyze(1), infer-capture(1), infer-compile(1),
    infer-debug
    (1), infer-explore(1), @@ -1404,108 +1406,108 @@

    OPTIONS infer-reportdiff(1), and infer-run(1).
    --help-issue-type
    +UNIQUE_ID

    -

    Show information about an issue +

    Show information about an issue type, for example NULL_DEREFERENCE. To see the list of all issue types, see --list-issue-types.

    -

    See also infer-help(1). +

    See also infer-help(1).
    --no-hoisting-report-only-expensive

    -

    Deactivates: [Hoisting] Report +

    Deactivates: [Hoisting] Report loop-invariant calls only when the function is expensive, i.e. at least linear (Conversely: --hoisting-report-only-expensive)

    -

    See also -infer-report(1).
    +

    See also infer-report(1). +
    --html

    -

    Activates: Generate an html +

    Activates: Generate an html report of issues found. (Conversely: --no-html)

    -

    See also +

    See also infer-explore(1).
    --impurity

    -

    Activates: impurity +

    Activates: impurity checker: Detects functions with potential side-effects. Same as "purity", but implemented on top of Pulse.

    -

    ACTIVATES: pulse +

    ACTIVATES: pulse (Conversely: --no-impurity)
    See also infer-analyze(1).
    --impurity-only

    -

    Activates: Enable +

    Activates: Enable impurity and disable all other checkers (Conversely: --no-impurity-only)

    -

    See also +

    See also infer-analyze(1).
    --impurity-report-immutable-modifications

    -

    Activates: Report modifications +

    Activates: Report modifications to immutable fields in the Impurity checker (Conversely: --no-impurity-report-immutable-modifications)

    -

    See also +

    See also infer-analyze(1).
    --incremental-analysis

    -

    Activates: Use incremental +

    Activates: Use incremental analysis for changed files. Not compatible with --reanalyze and --continue-analysis. Also sets --mark-unchanged-procs. (Conversely: --no-incremental-analysis)

    -

    See also +

    See also infer-analyze(1).
    --no-inefficient-keyset-iterator

    -

    Deactivates: +

    Deactivates: inefficient-keyset-iterator checker: Check for inefficient uses of iterators that iterate on keys then lookup their values, instead of iterating on key-value pairs directly. (Conversely: --inefficient-keyset-iterator)

    -

    See also +

    See also infer-analyze(1).
    --inefficient-keyset-iterator-only

    -

    Activates: Enable +

    Activates: Enable inefficient-keyset-iterator and disable all other checkers (Conversely: --no-inefficient-keyset-iterator-only)

    -

    See also +

    See also infer-analyze(1).
    --inline-func-pointer-for-testing
    string

    -

    Enables substituting global +

    Enables substituting global function pointers used for testing with the real function calls in the clang frontend. Pass the prefix used to build the global function pointers used for testing.

    -

    See also +

    See also infer-analyze(1).
    --invalidate-only

    -

    Activates: Remove any summaries +

    Activates: Remove any summaries from the results database that transitively depend on a changed procedure, then exit without doing any actual analysis. (Conversely: --no-invalidate-only)

    -

    See also +

    See also infer-analyze(1).
    --issues-tests
    file

    -

    Write a list of issues in a +

    Write a list of issues in a format suitable for tests to file

    -

    See also -infer-report(1).
    +

    See also infer-report(1). +
    --issues-tests-fields
    ,-separated sequence of { bug_type | bucket |
    qualifier | suggestion | severity | line | column | @@ -1516,173 +1518,173 @@

    OPTIONS
    transitive_callees_extra | suppressed | autofix }

    -

    Fields to emit with +

    Fields to emit with --issues-tests

    -

    See also -infer-report(1).
    +

    See also infer-report(1). +
    --java-jar-compiler
    path

    -

    Specify the Java compiler jar +

    Specify the Java compiler jar used to generate the bytecode

    -

    See also +

    See also infer-capture(1).
    --java-version
    int

    -

    The version of Java being used. +

    The version of Java being used. Set it to your Java version if mvn is failing.

    -

    See also -infer-analyze(1) and infer-capture(1).
    +

    See also infer-analyze(1) +and infer-capture(1).
    --jobs
    ,-j int

    -

    Run the specified number of +

    Run the specified number of analysis jobs simultaneously. Defaults to the minimum value of the max_jobs argument and the number of CPUs.

    -

    See also +

    See also infer-analyze(1).
    --keep-going

    -

    Activates: Keep going when the +

    Activates: Keep going when the analysis or capture encounter a failure (Conversely: --no-keep-going)

    -

    See also -infer-analyze(1) and infer-capture(1).
    +

    See also infer-analyze(1) +and infer-capture(1).
    --no-kotlin-capture

    -

    Deactivates: Enable Kotlin +

    Deactivates: Enable Kotlin capture. (Conversely: --kotlin-capture)

    -

    See also +

    See also infer-capture(1).
    --lineage

    -

    Activates: lineage +

    Activates: lineage checker: Computes a dataflow graph (Conversely: --no-lineage)

    -

    See also +

    See also infer-analyze(1).
    --no-lineage-dedup

    -

    Deactivates: In JSON output, +

    Deactivates: In JSON output, attempt to print each entity at most once. This is the default. The only reason you may want to turn this off is to make hash collisions more visible; that is, cases in which distinct entities get assigned the same ID. (Conversely: --lineage-dedup)

    -

    See also +

    See also infer-analyze(1).
    --lineage-field-depth
    int

    -

    [EXPERIMENTAL] Maximal field +

    [EXPERIMENTAL] Maximal field depth sensitivity for lineage analysis. 0 will make the analysis field insensitive.

    -

    See also +

    See also infer-analyze(1).
    --lineage-field-max-cfg-size
    int

    -

    If set, field sensitivity is +

    If set, field sensitivity is disabled on larger CFGs.

    -

    See also +

    See also infer-analyze(1).
    --lineage-field-width
    int

    -

    [EXPERIMENTAL] Maximal width of +

    [EXPERIMENTAL] Maximal width of structures for field sensitive lineage analysis. Structure that have a higher number of fields will be smashed into a single element. 0 will make the analysis field insensitive.

    -

    See also +

    See also infer-analyze(1).
    --lineage-include-builtins

    -

    Activates: Include call/return +

    Activates: Include call/return edges to/from procedures that model primitive Erlang operations, such as constructing a list. (Conversely: --no-lineage-include-builtins)

    -

    See also +

    See also infer-analyze(1).
    --lineage-json-report

    -

    Activates: Enable lineage +

    Activates: Enable lineage report in JSON format. (Conversely: --no-lineage-json-report)

    -

    See also +

    See also infer-analyze(1).
    --lineage-keep-temporaries

    -

    Activates: Normally, lineage +

    Activates: Normally, lineage summaries do not mention temporary variables introduced while compiling the high-level code to Infer's IR (intermediate representation). If this option is enabled, then the lineage graph produced corresponds to Infer's IR. (Conversely: --no-lineage-keep-temporaries)

    -

    See also +

    See also infer-analyze(1).
    --lineage-max-cfg-size
    int

    -

    If set, larger CFGs are +

    If set, larger CFGs are skipped.

    -

    See also +

    See also infer-analyze(1).
    --lineage-only

    -

    Activates: Enable +

    Activates: Enable lineage and disable all other checkers (Conversely: --no-lineage-only)

    -

    See also +

    See also infer-analyze(1).
    --no-lineage-prevent-cycles

    -

    Deactivates: [EXPERIMENTAL] If +

    Deactivates: [EXPERIMENTAL] If given, Lineage will not stop traversing the fields of a variable when it notices recursive types (that is, a sub-field having the same type as one of its "ancestors"). (Conversely: --lineage-prevent-cycles)

    -

    See also +

    See also infer-analyze(1).
    --lineage-sanitizers
    +string

    -

    [EXPERIMENTAL; UNSTABLE API] +

    [EXPERIMENTAL; UNSTABLE API] Lineage sanitizers, comma-separated m:f/a

    -

    See also -infer-report(1).
    +

    See also infer-report(1). +
    --lineage-seed
    int

    -

    Set the random seed used for +

    Set the random seed used for hashing. (Various entities that get reported need unique identifiers. To generate these unique identifiers, in a distributed way without communication, we use hashing. If you are unlucky and get collisions, you can try a different seed.

    -

    See also +

    See also infer-analyze(1).
    --lineage-sink
    +string

    -

    [EXPERIMENTAL; UNSTABLE API] +

    [EXPERIMENTAL; UNSTABLE API] Lineage sinks for taint finding, format [module:]function/arity.{ret,argN}, comma-separated. Must be used with --lineage-source as options to the report subcommand.

    -

    Will produce a graph +

    Will produce a graph materializing the flows between the sources
    and the sinks along with a json issues file. The issues file will
    @@ -1694,83 +1696,83 @@

    OPTIONS See also infer-report(1).
    --lineage-source
    +string

    -

    [EXPERIMENTAL; UNSTABLE API] +

    [EXPERIMENTAL; UNSTABLE API] Lineage sources for taint finding, format [module:]function/arity.{ret,argN}, comma-separated.

    -

    See --lineage-sink for +

    See --lineage-sink for additional documentation.
    See also infer-report(1).
    --lineage-variant-width
    int

    -

    Maximal width of variant types +

    Maximal width of variant types for lineage analysis. A variant type is the type of a variable whose value is within a statically known atom set. The width of the type is the cardinal of that atom set.

    -

    See also +

    See also infer-analyze(1).
    --list-categories

    -

    Activates: Show the list of all +

    Activates: Show the list of all categories of issue types that infer might report. (Conversely: --no-list-categories)

    -

    See also infer-help(1). +

    See also infer-help(1).
    --list-checkers

    -

    Activates: Show the list of all +

    Activates: Show the list of all available checkers. (Conversely: --no-list-checkers)

    -

    See also infer-help(1). +

    See also infer-help(1).
    --list-issue-types

    -

    Activates: Show the list of all +

    Activates: Show the list of all issue types that infer might report. (Conversely: --no-list-issue-types)

    -

    See also infer-help(1). +

    See also infer-help(1).
    --litho-required-props

    -

    Activates: +

    Activates: litho-required-props checker: Checks that all non-optional ‘@Prop‘s have been specified when constructing Litho components. (Conversely: --no-litho-required-props)

    -

    See also +

    See also infer-analyze(1).
    --litho-required-props-only

    -

    Activates: Enable +

    Activates: Enable litho-required-props and disable all other checkers (Conversely: --no-litho-required-props-only)

    -

    See also +

    See also infer-analyze(1).
    --no-liveness

    -

    Deactivates: liveness +

    Deactivates: liveness checker: Detection of dead stores and unused variables. (Conversely: --liveness)

    -

    See also +

    See also infer-analyze(1).
    --liveness-block-list-var-regex
    string

    -

    Specify a regular expression +

    Specify a regular expression for variable names that are ignored when reporting dead stores.

    -

    See also +

    See also infer-analyze(1).
    --liveness-dangerous-classes
    json

    -

    Specify classes where the +

    Specify classes where the destructor should be ignored when computing liveness. In other words, assignement to variables of these types (or common wrappers around these types such as @@ -1778,37 +1780,37 @@

    OPTIONS when the variables are not read explicitly by the program.

    -

    See also +

    See also infer-analyze(1).
    --liveness-ignored-constant
    +string

    -

    List of integer constants to be +

    List of integer constants to be ignored by liveness analysis

    -

    See also +

    See also infer-analyze(1).
    --liveness-only

    -

    Activates: Enable +

    Activates: Enable liveness and disable all other checkers (Conversely: --no-liveness-only)

    -

    See also +

    See also infer-analyze(1).
    --load-average
    ,-l float

    -

    Do not start new parallel jobs +

    Do not start new parallel jobs if the load average is greater than that specified (Buck and make only)

    -

    See also +

    See also infer-capture(1).
    --lock-model
    json

    -

    Specify custom lock models for +

    Specify custom lock models for starvation analysis.

    -

    Example for pthreads (already +

    Example for pthreads (already included in infer):
    [{"lock":["pthread_mutex_lock"],"unlock":["pthread_mutex_unlock"]}] @@ -1816,48 +1818,48 @@

    OPTIONS See also infer-analyze(1).
    --log-missing-deps

    -

    Activates: Log analysis +

    Activates: Log analysis dependencies that cannot be found. (Conversely: --no-log-missing-deps)

    -

    See also +

    See also infer-analyze(1).
    --log-pulse-coverage

    -

    Activates: Log precisely where +

    Activates: Log precisely where coverage stops, at the end of file stats/stats.txt. (Conversely: --no-log-pulse-coverage)

    -

    See also +

    See also infer-analyze(1).
    --log-pulse-disjunct-increase-after-model-call

    -

    Activates: Log which model did +

    Activates: Log which model did increase the current number of Pulse disjuncts. (Conversely: --no-log-pulse-disjunct-increase-after-model-call)

    -

    See also +

    See also infer-analyze(1).
    --loop-hoisting

    -

    Activates: loop-hoisting +

    Activates: loop-hoisting checker: Detect opportunities to hoist function calls that are invariant outside of loop bodies for efficiency. (Conversely: --no-loop-hoisting)

    -

    See also +

    See also infer-analyze(1).
    --loop-hoisting-only

    -

    Activates: Enable +

    Activates: Enable loop-hoisting and disable all other checkers (Conversely: --no-loop-hoisting-only)

    -

    See also +

    See also infer-analyze(1).
    --mark-unchanged-procs

    -

    Activates: Check structural +

    Activates: Check structural identity of newly-captured procedures with previously-captured versions, marking the new procedure as unchanged if the two are equivalent. Also prevents removing @@ -1865,121 +1867,129 @@

    OPTIONS reused during future incremental analyses (Conversely: --no-mark-unchanged-procs)

    -

    See also +

    See also infer-capture(1).
    --no-mask-sawja-exceptions

    -

    Deactivates: Mask exceptions +

    Deactivates: Mask exceptions thrown by Sawja/Javalib during Java capture (Conversely: --mask-sawja-exceptions)

    -

    See also +

    See also infer-capture(1).
    --max-jobs
    int

    -

    Maximum number of analysis jobs +

    Maximum number of analysis jobs running simultaneously. Experiments show current best value is 40 jobs.

    -

    See also +

    See also infer-analyze(1).
    --max-nesting
    int

    -

    Level of nested procedure calls +

    Level of nested procedure calls to show. Trace elements beyond the maximum nesting level are skipped. If omitted, all levels are shown.

    -

    See also +

    See also infer-explore(1).
    --memtrace-analysis-profiling

    -

    Activates: Generate OCaml +

    Activates: Generate OCaml analysis allocation traces in ‘infer-out/memtrace‘. (Conversely: --no-memtrace-analysis-profiling)

    -

    See also +

    See also infer-analyze(1).
    --memtrace-sampling-rate
    float

    -

    Sampling rate for Memtrace +

    Sampling rate for Memtrace allocation profiling. Default is 1e-6.

    -

    See also +

    See also infer-analyze(1).
    --merge-capture
    +string

    -

    Specifies an Infer results +

    Specifies an Infer results directory. The files and procedures captured in it will be merged together into the results directory specified with -o. Relative paths are interpreted as relative to project-root/buck-out.

    -

    See also +

    See also infer-capture(1).
    --merge-report
    +string

    -

    Specifies an Infer results +

    Specifies an Infer results directory. The reports stored in JSON files in all specified results directories will be merged together and deduplicated before being stored in the main results directory.

    -

    See also -infer-report(1).
    +

    See also infer-report(1). +
    --merge-summaries
    +string

    -

    Specifies an Infer results +

    Specifies an Infer results directory. The summaries in all specified results directories will be merged together and deduplicated before reporting is done.

    -

    See also -infer-report(1).
    +

    See also infer-report(1). +
    --modeled-expensive
    json

    -

    Matcher or list of matchers for +

    Matcher or list of matchers for methods that should be considered expensive by the performance critical checker.

    -

    See also +

    See also +infer-analyze(1).
    +--multicore

    + +

    Activates: [EXPERIMENTAL] uses +multi-threading for analysis, currently partially or not +implemented. (Conversely: --no-multicore)

    + +

    See also infer-analyze(1).
    --never-returning-null
    json

    -

    [Java only, all analyses] +

    [Java only, all analyses] Matcher or list of matchers for functions that never return null.

    -

    See also +

    See also infer-analyze(1), infer-capture(1), and infer-run(1).
    --noescaping-function-list
    +string

    -

    Useful for the check +

    Useful for the check CXX_REF_CAPTURED_IN_BLOCK. It declares a list of functions that take blocks as arguments that are no escaping but we cannot annotate them accordingly.

    -

    See also +

    See also infer-analyze(1).
    --objc-block-execution-macro
    string

    -

    Macro for executing Objective-C +

    Macro for executing Objective-C blocks safely.

    -

    See also +

    See also infer-analyze(1).
    --objc-synthesize-dealloc

    -

    Activates: If enabled, the +

    Activates: If enabled, the capture tries to synthesize code in the dealloc methods of Objective-C classes corresponding to what the compiler does. (Conversely: --no-objc-synthesize-dealloc)

    -

    See also +

    See also infer-capture(1).
    --ondemand-recursion-restart-limit
    int

    -

    In order to make the analysis +

    In order to make the analysis of mutual recursion cycles deterministic in their output, the analysis of a cycle of mutually recursive functions may restart the analysis of the entire cycle from a @@ -1990,122 +2000,122 @@

    OPTIONS restarts before we give up and analyze the cycle as-is instead.

    -

    See also +

    See also infer-analyze(1).
    --no-parameter-not-null-checked

    -

    Deactivates: +

    Deactivates: parameter-not-null-checked checker: An Objective-C-specific analysis to detect when a block parameter is used before being checked for null first. (Conversely: --parameter-not-null-checked)

    -

    See also +

    See also infer-analyze(1).
    --parameter-not-null-checked-only

    -

    Activates: Enable +

    Activates: Enable parameter-not-null-checked and disable all other checkers (Conversely: --no-parameter-not-null-checked-only)

    -

    See also +

    See also infer-analyze(1).
    --pmd-xml

    -

    Activates: Output issues in +

    Activates: Output issues in (PMD) XML format in infer-out/report.xml (Conversely: --no-pmd-xml)

    -

    See also infer-run(1). +

    See also infer-run(1).
    --preanalysis-html

    -

    Activates: Whether the HTML +

    Activates: Whether the HTML node printing for preanalysis is enabled or not. Set to false by default since this helps focus on debugging just the enabled analyses. (Conversely: --no-preanalysis-html)

    -

    See also infer-debug(1). +

    See also infer-debug(1).
    --print-active-checkers

    -

    Activates: Print the active +

    Activates: Print the active checkers before starting the analysis (Conversely: --no-print-active-checkers)

    -

    See also +

    See also infer-analyze(1).
    --print-logs

    -

    Activates: Also log messages to +

    Activates: Also log messages to stdout and stderr (Conversely: --no-print-logs)

    -

    See also +

    See also infer-analyze(1), infer-capture(1), infer-report(1), and
    infer-run
    (1).
    --procedures

    -

    Activates: Print functions and +

    Activates: Print functions and methods discovered by infer (Conversely: --no-procedures)

    -

    See also infer-debug(1). +

    See also infer-debug(1).
    --procedures-attributes

    -

    Activates: Print the attributes +

    Activates: Print the attributes of each procedure in the output of --procedures (Conversely: --no-procedures-attributes)

    -

    See also infer-debug(1). +

    See also infer-debug(1).
    --procedures-call-graph

    -

    Activates: Output a dotty file +

    Activates: Output a dotty file in infer-out/captured/syntactic-call-graph.dot. The graph is the syntactic call graph reachable from either all captured procedures or those determined by the option --changed-files-index. (Conversely: --no-procedures-call-graph)

    -

    See also infer-debug(1). +

    See also infer-debug(1).
    --procedures-callees

    -

    Activates: Print the static +

    Activates: Print the static callees of each procedure in the output of --procedures (Conversely: --no-procedures-callees)

    -

    See also infer-debug(1). +

    See also infer-debug(1).
    --procedures-cfg

    -

    Activates: Output a dotty file +

    Activates: Output a dotty file in infer-out/captured/<file_name>/<proc_name>.dot for each procedure in the output of --procedures (Conversely: --no-procedures-cfg)

    -

    See also infer-debug(1). +

    See also infer-debug(1).
    --no-procedures-definedness

    -

    Deactivates: Include procedures +

    Deactivates: Include procedures definedness in the output of --procedures, i.e. whether the procedure definition was found, or only the procedure declaration, or the procedure is an auto-generated Objective-C accessor (Conversely: --procedures-definedness)

    -

    See also infer-debug(1). +

    See also infer-debug(1).
    --procedures-filter
    filter

    -

    With --procedures, only +

    With --procedures, only print functions and methods (procedures) matching the specified filter. A procedure filter is of the form path_pattern:procedure_name. Patterns are interpreted @@ -2113,45 +2123,45 @@

    OPTIONS methods named "foo", one can use the filter ".*:foo", or "foo" for short.

    -

    See also infer-debug(1). +

    See also infer-debug(1).
    --procedures-name

    -

    Activates: Include procedures +

    Activates: Include procedures names in the output of --procedures (Conversely: --no-procedures-name)

    -

    See also infer-debug(1). +

    See also infer-debug(1).
    --no-procedures-source-file

    -

    Deactivates: Include the source +

    Deactivates: Include the source file in which the procedure definition or declaration was found in the output of --procedures (Conversely: --procedures-source-file)

    -

    See also infer-debug(1). +

    See also infer-debug(1).
    --procedures-summary

    -

    Activates: Print the summaries +

    Activates: Print the summaries of each procedure in the output of --procedures. See also --procedures-summary-skip-empty. (Conversely: --no-procedures-summary)

    -

    See also infer-debug(1). +

    See also infer-debug(1).
    --procedures-summary-json

    -

    Activates: Emit the summaries +

    Activates: Emit the summaries of each procedure in the output of --procedures as JSON (Conversely: --no-procedures-summary-json)

    -

    See also infer-debug(1). +

    See also infer-debug(1).
    --procedures-summary-skip-empty

    -

    Activates: Completely skip +

    Activates: Completely skip procedures that do not have summaries. Useful when analyzing a small part of a big project. (To use in conjunction with --procedures-summary or @@ -2159,72 +2169,72 @@

    OPTIONS --changed-files-index.) (Conversely: --no-procedures-summary-skip-empty)

    -

    See also infer-debug(1). +

    See also infer-debug(1).
    --procs-to-analyze-index
    file

    -

    Specify the file containing an +

    Specify the file containing an Sexp representing a list of pairs of procedures and specializations to analyze. Only works with the restart scheduler.

    -

    See also +

    See also infer-analyze(1).
    --no-progress-bar
    ,-P

    -

    Deactivates: Show a progress +

    Deactivates: Show a progress bar (Conversely: --progress-bar | -p)

    -

    See also infer-run(1). +

    See also infer-run(1).
    --progress-bar-style
    { auto | plain | multiline }

    -

    Style of the progress bar. +

    Style of the progress bar. auto selects multiline if connected to a tty, otherwise plain.

    -

    See also -infer-analyze(1) and infer-capture(1).
    +

    See also infer-analyze(1) +and infer-capture(1).
    --project-root
    ,-C dir

    -

    Specify the root directory of +

    Specify the root directory of the project

    -

    See also +

    See also infer-analyze(1), infer-capture(1), infer-report(1), and
    infer-run
    (1).
    --no-pulse

    -

    Deactivates: pulse +

    Deactivates: pulse checker: General-purpose memory and value analysis engine. (Conversely: --pulse)

    -

    See also +

    See also infer-analyze(1).
    --pulse-cut-to-one-path-procedures-pattern
    string

    -

    Regex of methods for which +

    Regex of methods for which pulse will only explore one path. Can be used on pathologically large procedures to prevent too-big states from being produced.

    -

    See also +

    See also infer-analyze(1).
    --pulse-inline-global-init-func-pointer

    -

    Activates: Inline the +

    Activates: Inline the initializer of global variables that are of type function pointer in Pulse. (Conversely: --no-pulse-inline-global-init-func-pointer)

    -

    See also +

    See also infer-analyze(1).
    --pulse-log-summary-count

    -

    Activates: Log the number of +

    Activates: Log the number of summaries (grouped by summary kind) for each analyzed procedure in Pulse. Results are put in JSON files under a 'pulse' subdirectory, one corresponding to each analysis @@ -2232,61 +2242,61 @@

    OPTIONS be needed. (Conversely: --no-pulse-log-summary-count)

    -

    See also +

    See also infer-analyze(1).
    --pulse-max-cfg-size
    int

    -

    Larger CFGs than the max size +

    Larger CFGs than the max size are skipped in Pulse.

    -

    See also +

    See also infer-analyze(1).
    --pulse-max-disjuncts
    int

    -

    Stop exploring new paths after +

    Stop exploring new paths after int disjunctions in the domain

    -

    See also +

    See also infer-analyze(1).
    --pulse-max-heap
    int

    -

    Give up analysing a procedure +

    Give up analysing a procedure if the number of words in the heap exceeds this limit. Intended use: avoid OutOfMemory crashes.

    -

    See also +

    See also infer-analyze(1).
    --pulse-model-abort
    +string

    -

    Methods that should be modelled +

    Methods that should be modelled as abort in Pulse

    -

    See also +

    See also infer-analyze(1).
    --pulse-model-alloc-pattern
    string

    -

    Regex of methods that should be +

    Regex of methods that should be modelled as allocs in Pulse

    -

    See also +

    See also infer-analyze(1).
    --pulse-model-cheap-copy-type
    regex

    -

    Regex of methods that should be +

    Regex of methods that should be cheap to copy in Pulse

    -

    See also +

    See also infer-analyze(1).
    --pulse-model-cheap-copy-type-list
    +regex

    -

    Regex of methods that should be +

    Regex of methods that should be cheap to copy in Pulse

    -

    See also +

    See also infer-analyze(1).
    --pulse-model-free-pattern
    string

    -

    Regex of methods that should be +

    Regex of methods that should be modelled as wrappers to free(3) in Pulse. The pointer to be freed should be the first argument of the function. This should only be needed if the code of the wrapper is not @@ -2294,113 +2304,113 @@

    OPTIONS (e.g. the call is dispatched to global function pointers).

    -

    See also +

    See also infer-analyze(1).
    --pulse-model-malloc-pattern
    string

    -

    Regex of methods that should be +

    Regex of methods that should be modelled as wrappers to malloc(3) in Pulse. The size to allocate should be the first argument of the function. See --pulse-model-free-pattern for more information.

    -

    See also +

    See also infer-analyze(1).
    --pulse-model-realloc-pattern
    string

    -

    Regex of methods that should be +

    Regex of methods that should be modelled as wrappers to realloc(3) in Pulse. The pointer to be reallocated should be the first argument of the function and the new size the second argument. See --pulse-model-free-pattern for more information.

    -

    See also +

    See also infer-analyze(1).
    --pulse-model-release-pattern
    string

    -

    Regex of methods that should be +

    Regex of methods that should be modelled as release in Pulse

    -

    See also +

    See also infer-analyze(1).
    --pulse-model-return-first-arg
    string

    -

    Regex of methods that should be +

    Regex of methods that should be modelled as returning the first argument in Pulse in terms of the source language semantics. Languages supported: Java, C, Objective-C

    -

    See also +

    See also infer-analyze(1).
    --pulse-model-return-nonnull
    string

    -

    Regex of methods that should be +

    Regex of methods that should be modelled as returning non-null in Pulse

    -

    See also +

    See also infer-analyze(1).
    --pulse-model-return-nonnull-list
    +string

    -

    Regex of methods that should be +

    Regex of methods that should be modelled as returning non-null in Pulse

    -

    See also +

    See also infer-analyze(1).
    --pulse-model-return-this
    string

    -

    Regex of methods that should be +

    Regex of methods that should be modelled as returning the ‘this‘ or ‘self‘ argument of an instance method in Pulse. Languages supported: Java, Objective-C

    -

    See also +

    See also infer-analyze(1).
    --pulse-model-returns-copy-pattern
    string

    -

    Regex of methods that should be +

    Regex of methods that should be modelled as creating copies in Pulse

    -

    See also +

    See also infer-analyze(1).
    --pulse-model-skip-pattern
    string

    -

    Regex of methods that should be +

    Regex of methods that should be modelled as "skip" in Pulse

    -

    See also +

    See also infer-analyze(1).
    --pulse-model-skip-pattern-list
    +string

    -

    Regex of methods that should be +

    Regex of methods that should be modelled as "skip" in Pulse

    -

    See also +

    See also infer-analyze(1).
    --pulse-model-transfer-ownership
    +string

    -

    Methods that should be modelled +

    Methods that should be modelled as transfering memory ownership in Pulse. Accepted formats are method or namespace::method

    -

    See also +

    See also infer-analyze(1).
    --pulse-model-unknown-pure
    +string

    -

    Regex of methods that should be +

    Regex of methods that should be modelled as unknown pure in Pulse

    -

    See also +

    See also infer-analyze(1).
    --pulse-model-unreachable
    +string

    -

    Methods to be modeled as +

    Methods to be modeled as unreachable.

    -

    See also +

    See also infer-analyze(1).
    --pulse-models-for-erlang
    +path

    -

    Provide custom models for +

    Provide custom models for Erlang in JSON files or SQLite3. Files must end with ‘.json‘ or ‘.db‘ respectively. If a path to a directory is given then the subdirectories will be @@ -2408,7 +2418,7 @@

    OPTIONS format is preferable when providing a large number of models because they will be internally indexed by mfa.

    -

    The format for JSON is +

    The format for JSON is [SelectorBehavior, ...] where
    SelectorBehavior := {"selector": Selector, "behavior": Behavior}
    @@ -2450,86 +2460,86 @@

    OPTIONS See also infer-analyze(1).
    --no-pulse-nullsafe-report-npe

    -

    Deactivates: Report null +

    Deactivates: Report null dereference issues on files marked @Nullsafe. (Conversely: --pulse-nullsafe-report-npe)

    -

    See also +

    See also infer-analyze(1).
    --pulse-nullsafe-report-npe-as-separate-issue

    -

    Activates: Report null +

    Activates: Report null dereference issues on files marked @Nullsafe as a separate NULLPTR_DEREFERENCE_IN_NULLSAFE_CLASS issue type. (Conversely: --no-pulse-nullsafe-report-npe-as-separate-issue)

    -

    See also +

    See also infer-analyze(1).
    --pulse-only

    -

    Activates: Enable pulse +

    Activates: Enable pulse and disable all other checkers (Conversely: --no-pulse-only)

    -

    See also +

    See also infer-analyze(1).
    --pulse-over-approximate-reasoning

    -

    Activates: [EXPERIMENTAL] add +

    Activates: [EXPERIMENTAL] add over-approximate reasoning on top of the under-approximate, disjunctive reasoning of Pulse. (Conversely: --no-pulse-over-approximate-reasoning)

    -

    See also +

    See also infer-analyze(1).
    --pulse-recency-limit
    int

    -

    Maximum number of array +

    Maximum number of array elements and structure fields to keep track of for a given address.

    -

    See also +

    See also infer-analyze(1).
    --pulse-report-flows-from-taint-source
    procname

    -

    Report data flows which +

    Report data flows which originate at taint source procname

    -

    See also -infer-report(1).
    +

    See also infer-report(1). +
    --pulse-report-flows-to-taint-sink
    procname

    -

    Report data flows which pass +

    Report data flows which pass through taint sink procname

    -

    See also -infer-report(1).
    +

    See also infer-report(1). +
    --pulse-skip-procedures
    regex

    -

    Regex of procedures that should +

    Regex of procedures that should not be analyzed by Pulse.

    -

    See also +

    See also infer-analyze(1).
    --pulse-specialization-iteration-limit
    int

    -

    Maximum number of iterative +

    Maximum number of iterative summary specialization at each call site.

    -

    See also +

    See also infer-analyze(1).
    --pulse-specialization-limit
    int

    -

    Maximum number of summary +

    Maximum number of summary specialization by procedure.

    -

    See also +

    See also infer-analyze(1).
    --pulse-taint-config
    +path

    -

    Path to a taint analysis +

    Path to a taint analysis configuration file or a directory containing such files. This file can define --pulse-taint-sources, --pulse-taint-sanitizers, @@ -2537,7 +2547,7 @@

    OPTIONS --pulse-taint-sinks, --pulse-taint-policies, and --pulse-taint-data-flow-kinds.

    -

    If a path to a directory is +

    If a path to a directory is given then the configuration files
    must have the ‘.json‘ extension. Any other file will be ignored.
    @@ -2547,40 +2557,39 @@

    OPTIONS See also infer-analyze(1).
    --pulse-taint-data-flow-kinds
    json

    -

    Specify which taint kinds +

    Specify which taint kinds should be used for data flow reporting only. If a source has such a kind, only data flows to sinks which originate at the source will be reported. If a sink has such a kind, only sensitive data flows to the sink will be reported.

    -

    See also +

    See also infer-analyze(1).
    --no-pulse-taint-follow-field-accesses

    -

    Deactivates: Specify if taint +

    Deactivates: Specify if taint analysis should follow field accesses when propagating taints. (Conversely: --pulse-taint-follow-field-accesses)

    -

    See also +

    See also infer-analyze(1).
    --pulse-taint-opaque-files
    +path

    -

    Specify files that should be +

    Specify files that should be treated as opaque for taint analysis to make sure that procedure's belonging to these files are always free of any potential taint flows.

    -

    See also +

    See also infer-analyze(1).
    --pulse-taint-policies
    json

    -

    A description of which taint +

    A description of which taint flows should be reported, following this JSON format:

    -

    { -"short_description": "<a short description -of the issue>",
    +

    { "short_description": +"<a short description of the issue>",
    "taint_flows": [{ "source_kinds": [<kinds>],
    "sink_kinds": [<kinds>],
    @@ -2607,52 +2616,52 @@

    OPTIONS See also infer-analyze(1).
    --pulse-taint-propagators
    json

    -

    Quick way to specify simple +

    Quick way to specify simple propagators as a JSON objects. See --pulse-taint-sources for the fields format documentation.

    -

    See also +

    See also infer-analyze(1).
    --pulse-taint-sanitizers
    json

    -

    Quick way to specify simple +

    Quick way to specify simple sanitizers as a JSON objects. See --pulse-taint-sources for the fields format documentation.

    -

    See also +

    See also infer-analyze(1).
    --pulse-taint-short-traces

    -

    Activates: Cut off taint traces +

    Activates: Cut off taint traces as soon as a tainted value flows into a sink. This matters when the sink itself calls other sinks of the same kind and as long as the value flows from call to call, without this flag the trace would include the whole chain of calls. (Conversely: --no-pulse-taint-short-traces)

    -

    See also +

    See also infer-analyze(1).
    --pulse-taint-sinks
    json

    -

    Quick way to specify simple +

    Quick way to specify simple sinks as a JSON objects. See --pulse-taint-sources for the fields format documentation.

    -

    See also +

    See also infer-analyze(1).
    --pulse-taint-skip-sources

    -

    Activates: Skip the analysis of +

    Activates: Skip the analysis of methods declared as sources in the taint. (Conversely: --no-pulse-taint-skip-sources)

    -

    See also +

    See also infer-analyze(1).
    --pulse-taint-sources
    json

    -

    Together with +

    Together with --pulse-taint-sanitizers, --pulse-taint-sinks, --pulse-taint-policies, and --pulse-taint-data-flow-kinds, specify taint @@ -2661,8 +2670,8 @@

    OPTIONS one of the following combinations of fields to identify relevant procedures:

    -

    - "field_regex": -match a field name using an OCaml regex
    +

    - "field_regex": match +a field name using an OCaml regex
    - "procedure": match a substring of the procedure name
    - "procedure_regex": as above, but match using an @@ -2770,143 +2779,130 @@

    OPTIONS See also infer-analyze(1).
    --pulse-unsafe-malloc

    -

    Activates: Assume that +

    Activates: Assume that malloc(3) never returns null. (Conversely: --no-pulse-unsafe-malloc)

    -

    See also +

    See also infer-analyze(1).
    --pulse-widen-threshold
    int

    -

    Stop exploring new paths after +

    Stop exploring new paths after int loop iterations

    -

    See also +

    See also infer-analyze(1).
    --purity

    -

    Activates: purity +

    Activates: purity checker: Detects pure (side-effect-free) functions. A different implementation of "impurity". (Conversely: --no-purity)

    -

    See also +

    See also infer-analyze(1).
    --purity-only

    -

    Activates: Enable purity +

    Activates: Enable purity and disable all other checkers (Conversely: --no-purity-only)

    -

    See also +

    See also infer-analyze(1).
    --python-files-index
    path

    -

    A file containing a list of +

    A file containing a list of newline-separated Python files to capture. Compatible with infer capture -- python3 file1.py file2.py but not with --pyc-file.

    -

    See also +

    See also infer-capture(1).
    ---python-globals
    { own-by-closures | own-by-module -}

    - -

    Specify the strategy to wire -globals dictionnaire into each function

    - -

    - own-by-closures: each closure -captured the global
    -dictionary
    -- own-by-module: each function is given the global -dictionary as
    -argument (not referenced in the heap to avoid aliases)
    -See also infer-analyze(1).
    --qualified-cpp-name-block-list
    +string

    -

    Skip analyzing the procedures +

    Skip analyzing the procedures under the qualified cpp type name.

    -

    See also +

    See also infer-analyze(1).
    --quiet
    ,-q

    -

    Activates: Do not print +

    Activates: Do not print anything on standard output. (Conversely: --no-quiet | -Q)

    -

    See also -infer-analyze(1) and infer-report(1).
    +

    See also infer-analyze(1) +and infer-report(1).
    --no-racerd

    -

    Deactivates: racerd +

    Deactivates: racerd checker: Thread safety analysis. (Conversely: --racerd)

    -

    See also +

    See also infer-analyze(1).
    --racerd-always-report-java

    -

    Activates: Every Java class +

    Activates: Every Java class analysed is treated as if it were annotated as @ThreadSafe. (Conversely: --no-racerd-always-report-java)

    -

    See also +

    See also infer-analyze(1).
    --racerd-guardedby

    -

    Activates: Check @GuardedBy +

    Activates: Check @GuardedBy annotations with RacerD (Conversely: --no-racerd-guardedby)

    -

    See also +

    See also infer-analyze(1).
    --racerd-ignore-classes
    +string

    -

    Any method in a class specified +

    Any method in a class specified here will be ignored by RacerD.

    -

    See also +

    See also infer-analyze(1).
    --racerd-only

    -

    Activates: Enable racerd +

    Activates: Enable racerd and disable all other checkers (Conversely: --no-racerd-only)

    -

    See also +

    See also infer-analyze(1).
    --reactive
    ,-r

    -

    Activates: Reactive mode: the +

    Activates: Reactive mode: the analysis starts from the files captured since the infer command started (Conversely: --no-reactive | -R)

    -

    See also +

    See also infer-analyze(1).
    --reactive-capture

    -

    Activates: Reactive capture: +

    Activates: Reactive capture: capture and analysis are interleaved. Currently this flag will only make the analysis generate a list of type names that were not found in the global tenv. The feature is only available for the Hack frontend for now. (Conversely: --no-reactive-capture)

    -

    See also +

    See also infer-analyze(1).
    --no-read-java-modules

    -

    Deactivates: Read java modules +

    Deactivates: Read java modules file using jimage. (Conversely: --read-java-modules)

    -

    See also +

    See also infer-capture(1).
    --replay-analysis-schedule

    -

    Activates: Replay the analysis +

    Activates: Replay the analysis schedule stored in --replay-analysis-schedule-file, which should analyze the procedures in the same order as the previous analysis. This should drastically limit @@ -2915,11 +2911,11 @@

    OPTIONS previous analysis has just run on the same code. (Conversely: --no-replay-analysis-schedule)

    -

    See also +

    See also infer-analyze(1).
    --replay-ondemand-should-error

    -

    Activates: [debug] Whether +

    Activates: [debug] Whether triggering the analysis of a procedure via ondemand should log an error when replaying an analysis schedule with --replay-analysis-schedule. Enable when replaying the @@ -2927,47 +2923,47 @@

    OPTIONS dependencies that were recorded are insufficient. (Conversely: --no-replay-ondemand-should-error)

    -

    See also +

    See also infer-analyze(1).
    --no-report

    -

    Deactivates: Run the reporting +

    Deactivates: Run the reporting phase once the analysis has completed (Conversely: --report)

    -

    See also -infer-analyze(1) and infer-run(1).
    +

    See also infer-analyze(1) +and infer-run(1).
    --report-allow-list-path-regex
    +path_regex

    -

    Report issues only on files +

    Report issues only on files whose relative path matches the specified OCaml regex (and which do not match --report-block-list-path-regex)

    -

    See also infer-report(1) +

    See also infer-report(1) and infer-run(1).
    --report-block-list-files-containing
    +string

    -

    Do not report any issues on +

    Do not report any issues on files containing the specified string

    -

    See also infer-report(1) +

    See also infer-report(1) and infer-run(1).
    --report-block-list-path-regex
    +path_regex

    -

    Do not report any issues on +

    Do not report any issues on files whose relative path matches the specified OCaml regex, even if they match the allow list specified by --report-allow-list-path-regex

    -

    See also infer-report(1) +

    See also infer-report(1) and infer-run(1).
    --report-block-list-spec
    json

    -

    Do not report the issues in +

    Do not report the issues in this list.

    -

    Example format:
    +

    Example format:
    "report-block-list-spec": [
    { "bug_type": "CXX_REF_CAPTURED_IN_BLOCK",
    @@ -2986,80 +2982,80 @@

    OPTIONS
    --report-console-limit
    int

    -

    Maximum number of issues to +

    Maximum number of issues to display on standard output. Unset with --report-console-limit-reset to show all.

    -

    See also -infer-report(1).
    +

    See also infer-report(1). +
    --report-current
    path

    -

    report of the latest +

    report of the latest revision

    -

    See also +

    See also infer-reportdiff(1).
    --report-force-relative-path

    -

    Activates: Force converting an +

    Activates: Force converting an absolute path to a relative path to the root directory (Conversely: --no-report-force-relative-path)

    -

    See also -infer-analyze(1) and infer-run(1).
    +

    See also infer-analyze(1) +and infer-run(1).
    --report-formatter
    { none | phabricator }

    -

    Which formatter to use when +

    Which formatter to use when emitting the report

    -

    See also -infer-report(1).
    +

    See also infer-report(1). +
    --report-previous
    path

    -

    Report of the base revision to +

    Report of the base revision to use for comparison

    -

    See also +

    See also infer-reportdiff(1).
    --report-suppress-errors
    +error_name

    -

    do not report a type of +

    do not report a type of errors

    -

    See also infer-report(1) +

    See also infer-report(1) and infer-run(1).
    --results-dir
    ,-o dir

    -

    Write results and internal +

    Write results and internal files in the specified directory

    -

    See also +

    See also infer-analyze(1), infer-capture(1), infer-explore(1),
    infer-report
    (1), and infer-run(1).
    --run-python-interpreter

    -

    Activates: Capture all .py +

    Activates: Capture all .py files, transform them into internal PyIR form and run the PyIR interpreter on them. (Conversely: --no-run-python-interpreter)

    -

    See also +

    See also infer-capture(1).
    --sarif

    -

    Activates: Output issues in +

    Activates: Output issues in SARIF (Static Analysis Results Interchange Format) in infer-out/report.sarif (Conversely: --no-sarif)

    -

    See also infer-run(1). +

    See also infer-run(1).
    --scheduler
    { file | restart | callgraph }

    -

    Specify the scheduler used for +

    Specify the scheduler used for the analysis phase:

    -

    - file: schedules one job per +

    - file: schedules one job per file
    - callgraph: schedules one job per procedure, following the
    @@ -3073,7 +3069,7 @@

    OPTIONS See also infer-analyze(1).
    --scope-leakage

    -

    Activates: scope-leakage +

    Activates: scope-leakage checker: The Java/Kotlin checker takes into account a set of "scope" annotations and a must-not-hold relation over the scopes. The checker raises an alarm if there exists @@ -3081,325 +3077,325 @@

    OPTIONS respective scopes SA and SB, such that must-not-hold(SA, SB). (Conversely: --no-scope-leakage)

    -

    See also +

    See also infer-analyze(1).
    --scope-leakage-only

    -

    Activates: Enable +

    Activates: Enable scope-leakage and disable all other checkers (Conversely: --no-scope-leakage-only)

    -

    See also +

    See also infer-analyze(1).
    --select
    (N|all)

    -

    Select option number N +

    Select option number N or all of them. If omitted, prompt for input.

    -

    See also infer-debug(1) +

    See also infer-debug(1) and infer-explore(1).
    --no-self-in-block

    -

    Deactivates: +

    Deactivates: self-in-block checker: An Objective-C-specific analysis to detect when a block captures ‘self‘. (Conversely: --self-in-block)

    -

    See also +

    See also infer-analyze(1).
    --self-in-block-only

    -

    Activates: Enable +

    Activates: Enable self-in-block and disable all other checkers (Conversely: --no-self-in-block-only)

    -

    See also +

    See also infer-analyze(1).
    --shrink-analysis-db

    -

    Activates: After analysis, +

    Activates: After analysis, delete analysis summaries (but not report summaries) and vacuum analysis database. (Conversely: --no-shrink-analysis-db)

    -

    See also +

    See also infer-analyze(1).
    --sil-validation

    -

    Activates: +

    Activates: sil-validation checker: This checker validates that all SIL instructions in all procedure bodies conform to a (front-end specific) subset of SIL. (Conversely: --no-sil-validation)

    -

    See also +

    See also infer-analyze(1).
    --sil-validation-only

    -

    Activates: Enable +

    Activates: Enable sil-validation and disable all other checkers (Conversely: --no-sil-validation-only)

    -

    See also +

    See also infer-analyze(1).
    --no-siof

    -

    Deactivates: siof +

    Deactivates: siof checker: Catches Static Initialization Order Fiascos in C++, that can lead to subtle, compiler-version-dependent errors. (Conversely: --siof)

    -

    See also +

    See also infer-analyze(1).
    --siof-check-iostreams

    -

    Activates: Do not assume that +

    Activates: Do not assume that iostreams (cout, cerr, ...) are always initialized. The default is to assume they are always initialized to avoid false positives. However, if your program compiles against a recent libstdc++ then it is safe to turn this option on. (Conversely: --no-siof-check-iostreams)

    -

    See also +

    See also infer-analyze(1).
    --siof-only

    -

    Activates: Enable siof +

    Activates: Enable siof and disable all other checkers (Conversely: --no-siof-only)

    -

    See also +

    See also infer-analyze(1).
    --siof-safe-methods
    +string

    -

    Methods that are SIOF-safe; +

    Methods that are SIOF-safe; "foo::bar" will match "foo::bar()", "foo<int>::bar()", etc. (can be specified multiple times)

    -

    See also +

    See also infer-analyze(1).
    --skip-analysis-in-path
    +regex

    -

    Ignore files whose path matches +

    Ignore files whose path matches a given regex (can be specified multiple times, but you must make sure each regex is properly bracketed)

    -

    See also -infer-capture(1) and infer-run(1).
    +

    See also infer-capture(1) +and infer-run(1).
    --skip-analysis-in-path-skips-compilation

    -

    Activates: Whether paths in +

    Activates: Whether paths in --skip-analysis-in-path should be compiled or not (Conversely: --no-skip-analysis-in-path-skips-compilation)

    -

    See also -infer-report(1).
    +

    See also infer-report(1). +
    --no-skip-duplicated-types

    -

    Deactivates: Skip +

    Deactivates: Skip fixed-then-introduced duplicated types while computing differential reports (Conversely: --skip-duplicated-types)

    -

    See also +

    See also infer-reportdiff(1).
    --skip-non-capture-clang-commands

    -

    Activates: Skip clang commands +

    Activates: Skip clang commands that Infer doesn't use to capture data (Conversely: --no-skip-non-capture-clang-commands)

    -

    See also +

    See also infer-capture(1).
    --skip-translation-headers
    +path_regex

    -

    Ignore declarations in headers +

    Ignore declarations in headers whose path matches the given OCaml regex from the start of the string during capture.

    -

    See also +

    See also infer-capture(1).
    --source-files

    -

    Activates: Print source files +

    Activates: Print source files discovered by infer (Conversely: --no-source-files)

    -

    See also infer-debug(1). +

    See also infer-debug(1).
    --source-files-call-graph

    -

    Activates: Output a dotty file +

    Activates: Output a dotty file in infer-out/captured/file-call-graph.dot. The graph is the file-based syntactic call graph of all captured procedures (with known translation units). (Conversely: --no-source-files-call-graph)

    -

    See also infer-debug(1). +

    See also infer-debug(1).
    --source-files-call-graph-partition
    int

    -

    The number of partitions to +

    The number of partitions to divide the set of captured source files, using static call graph information. The generated file lists are found under infer-out/captured/workerXX.idx. Not setting this option skips partitioning. This is used for distributed analysis.

    -

    See also infer-debug(1). +

    See also infer-debug(1).
    --source-files-cfg

    -

    Activates: Output a dotty file +

    Activates: Output a dotty file in infer-out/captured for each source file in the output of --source-files (Conversely: --no-source-files-cfg)

    -

    See also infer-debug(1). +

    See also infer-debug(1).
    --source-files-filter
    filter

    -

    With --source-files, +

    With --source-files, only print source files matching the specified filter. The filter is a pattern that should match the file path. Patterns are interpreted as OCaml Str regular expressions.

    -

    See also infer-debug(1). +

    See also infer-debug(1).
    --source-files-freshly-captured

    -

    Activates: Print whether the +

    Activates: Print whether the source file has been captured in the most recent capture phase in the output of --source-files. (Conversely: --no-source-files-freshly-captured)

    -

    See also infer-debug(1). +

    See also infer-debug(1).
    --source-files-procedure-names

    -

    Activates: Print the names of +

    Activates: Print the names of procedure of each source file in the output of --source-files (Conversely: --no-source-files-procedure-names)

    -

    See also infer-debug(1). +

    See also infer-debug(1).
    --source-files-type-environment

    -

    Activates: Print the type +

    Activates: Print the type environment of each source file in the output of --source-files (Conversely: --no-source-files-type-environment)

    -

    See also infer-debug(1). +

    See also infer-debug(1).
    --no-source-preview

    -

    Deactivates: print code +

    Deactivates: print code excerpts around trace elements (Conversely: --source-preview)

    -

    See also +

    See also infer-explore(1).
    --sqlite-cache-size
    int

    -

    SQLite cache size in pages (if +

    SQLite cache size in pages (if positive) or kB (if negative), follows formal of corresponding SQLite PRAGMA.

    -

    See also +

    See also infer-analyze(1), infer-capture(1), and infer-run(1).
    --sqlite-lock-timeout
    int

    -

    Timeout for SQLite results +

    Timeout for SQLite results database operations, in milliseconds.

    -

    See also +

    See also infer-analyze(1), infer-capture(1), and infer-run(1).
    --sqlite-max-blob-size
    int

    -

    Maximum blob/string size for +

    Maximum blob/string size for data written in SQLite.

    -

    See also +

    See also infer-analyze(1), infer-capture(1), and infer-run(1).
    --sqlite-mmap-size
    int

    -

    Size of memory map for mmaped +

    Size of memory map for mmaped SQLite databases, zero value disables memory mapping.

    -

    See also +

    See also infer-analyze(1), infer-capture(1), and infer-run(1).
    --sqlite-page-size
    int

    -

    SQLite page size in bytes, must +

    SQLite page size in bytes, must be a power of two between 512 and 65536.

    -

    See also +

    See also infer-analyze(1), infer-capture(1), and infer-run(1).
    --no-starvation

    -

    Deactivates: starvation +

    Deactivates: starvation checker: Detect various kinds of situations when no progress is being made because of concurrency errors. (Conversely: --starvation)

    -

    See also +

    See also infer-analyze(1).
    --starvation-only

    -

    Activates: Enable +

    Activates: Enable starvation and disable all other checkers (Conversely: --no-starvation-only)

    -

    See also +

    See also infer-analyze(1).
    --no-static-constructor-stall-checker

    -

    Deactivates: +

    Deactivates: static-constructor-stall-checker checker: Detect if dispatch_once is called from a static constructor. (Conversely: --static-constructor-stall-checker)

    -

    See also +

    See also infer-analyze(1).
    --static-constructor-stall-checker-only

    -

    Activates: Enable +

    Activates: Enable static-constructor-stall-checker and disable all other checkers (Conversely: --no-static-constructor-stall-checker-only)

    -

    See also +

    See also infer-analyze(1).
    --stats-dir-current
    path

    -

    The infer-out/stats from the +

    The infer-out/stats from the current run. Together with --stats-dir-previous, make infer reportdiff compute the difference between two stats directories and output the results in infer-out/differential/stats_*.json files.

    -

    See also +

    See also infer-reportdiff(1).
    --stats-dir-previous
    path

    -

    The infer-out/stats from a +

    The infer-out/stats from a previous run. See --stats-dir-current.

    -

    See also +

    See also infer-reportdiff(1).
    --store-analysis-schedule

    -

    Activates: Store the analysis +

    Activates: Store the analysis schedule for later replay, honoring --replay-analysis-schedule-file if present. This can be useful to store a schedule done with one version of infer @@ -3410,108 +3406,108 @@

    OPTIONS successfully as fewer datatypes are involved. (Conversely: --no-store-analysis-schedule)

    -

    See also +

    See also infer-analyze(1).
    --struct-as-cpp-class

    -

    Activates: Translate C structs +

    Activates: Translate C structs as C++ classes. This can be useful when analyzing C/C++ code to make sure struct global variables shared between C and C++ source files are treated as same variables

    -

    (Conversely: +

    (Conversely: --no-struct-as-cpp-class)
    See also infer-capture(1).
    --no-suppressions

    -

    Deactivates: Suppress infer +

    Deactivates: Suppress infer issues on source lines matching the @infer-disable ISSUE_TYPE1, ISSUE_TYPE2, ... and @infer-disable-every ISSUE_TYPE1, ISSUE_TYPE2, ... keywords. (Conversely: --suppressions)

    -

    See also -infer-report(1).
    +

    See also infer-report(1). +
    --tenv-json
    file

    -

    Path to TEnv json file

    +

    Path to TEnv json file

    -

    See also +

    See also infer-capture(1).
    --threadsafe-aliases
    json

    -

    Specify custom annotations that +

    Specify custom annotations that should be considered aliases of @ThreadSafe

    -

    See also +

    See also infer-analyze(1).
    --timeout
    float

    -

    Time after which any checker +

    Time after which any checker (except biabduction) should give up analysing the current function or method, in seconds

    -

    See also -infer-analyze(1) and infer-run(1).
    +

    See also infer-analyze(1) +and infer-run(1).
    --top-longest-proc-duration-size
    int

    -

    Number of procedures for which +

    Number of procedures for which we track longest analysis duration info.

    -

    See also +

    See also infer-analyze(1).
    --topl

    -

    Activates: topl checker: +

    Activates: topl checker: Detect errors based on user-provided state machines describing temporal properties over multiple objects.

    -

    ACTIVATES: pulse +

    ACTIVATES: pulse (Conversely: --no-topl)
    See also infer-analyze(1).
    --topl-only

    -

    Activates: Enable topl +

    Activates: Enable topl and disable all other checkers (Conversely: --no-topl-only)

    -

    See also +

    See also infer-analyze(1).
    --version

    -

    Print version information and +

    Print version information and exit

    -

    See also infer-run(1). +

    See also infer-run(1).
    --version-json

    -

    Print version information in +

    Print version information in json format and exit

    -

    See also infer-run(1). +

    See also infer-run(1).
    --workspace
    path

    -

    Specifies the root of the +

    Specifies the root of the workspace, which is a directory containing --project-root. This can be needed if the capture phase is expected to require several different project roots, all relative to a common workspace. Usually a single project root is enough, though.

    -

    See also +

    See also infer-capture(1).
    --write-html

    -

    Activates: Produce html debug +

    Activates: Produce html debug output for the analyses in infer-out/captured. This shows the abstract state of all analyses at each program point in the source code. Each captured source file has its own html page. This HTML file contains the source file, and at each line of

    -

    the file there are links to the +

    the file there are links to the nodes of the control flow graph
    of Infer's translation of that line of code into its intermediate
    @@ -3523,120 +3519,120 @@

    OPTIONS See also infer-analyze(1).
    --write-website
    path_to_website_dir

    -

    Use to write website files +

    Use to write website files documenting issue types and checkers under path_to_website_dir/. Meant to be used within the Infer directory to generate its website at fbinfer.com at website/.

    -

    See also infer-help(1). +

    See also infer-help(1).
    --Xbuck
    +string

    -

    Pass values as command-line +

    Pass values as command-line arguments to invocations of ‘buck build‘. Only valid for --buck-clang.

    -

    See also +

    See also infer-capture(1).
    --Xbuck-no-inline
    +string

    -

    Pass values as command-line +

    Pass values as command-line arguments to invocations of ‘buck build‘, don't inline any args starting with '@'. Only valid for --buck-clang.

    -

    See also +

    See also infer-capture(1).
    --Xbuck2
    +string

    -

    Pass values as command-line +

    Pass values as command-line arguments to invocations of ‘buck2 build‘. Only valid for --buck-clang.

    -

    See also +

    See also infer-capture(1).
    --Xbuck2-no-inline
    +string

    -

    Pass values as command-line +

    Pass values as command-line arguments to invocations of ‘buck2 build‘, don't inline any args starting with '@'. Only valid for --buck-clang.

    -

    See also +

    See also infer-capture(1).
    --Xclang
    +string

    -

    Pass values as command-line +

    Pass values as command-line arguments to invocations of clang

    -

    See also +

    See also infer-capture(1).
    --xcode-developer-dir
    XCODE_DEVELOPER_DIR

    -

    Specify the path to Xcode +

    Specify the path to Xcode developer directory, to use for Buck clang targets

    -

    See also +

    See also infer-capture(1).
    --xcode-isysroot-suffix
    string

    -

    Specify the suffix of Xcode +

    Specify the suffix of Xcode isysroot directory, to avoid absolute paths in tests

    -

    See also +

    See also infer-analyze(1).
    --xcpretty

    -

    Activates: Infer will use +

    Activates: Infer will use xcpretty together with xcodebuild to analyze an iOS app. xcpretty just needs to be in the path, infer command is still just ‘infer -- <xcodebuild command>‘. (Conversely: --no-xcpretty)

    -

    See also +

    See also infer-capture(1).

    - + - - +

    --

    +

    Stop argument processing, use remaining arguments as a build command

    -

    See also -infer-capture(1) and infer-run(1).

    +

    See also infer-capture(1) +and infer-run(1).

    ENVIRONMENT

    -

    Extra arguments +

    Extra arguments may be passed to all infer commands using the INFER_ARGS environment variable (see the OPTIONS section). INFER_ARGS is expected to -contain a string of ^-separated options. For instance, -calling ‘INFER_ARGS=--debug^--print-logs infer‘ -is equivalent to calling ‘infer --debug +contain a string of ˆ-separated options. For instance, +calling ‘INFER_ARGS=--debugˆ--print-logs +infer‘ is equivalent to calling ‘infer --debug --print-logs‘.

    -

    INFERCONFIG: +

    INFERCONFIG: Tells infer where to find the .inferconfig file. (See the FILES section)

    -

    If +

    If INFER_STRICT_MODE is set to "1", then infer commands will exit with an error code in some cases when otherwise a simple warning would be emitted on stderr, for @@ -3648,7 +3644,7 @@

    FILES -

    .inferconfig +

    .inferconfig can be used to store infer options. Its format is that of a JSON record, where fields are infer long-form options, without their leading "--", and values depend on @@ -3666,7 +3662,7 @@

    FILES - cumulative options are JSON arrays of the appropriate type

    -

    If an +

    If an .inferconfig file is specified on the command line with --inferconfig-path then Infer will use that. Otherwise, Infer will look for an .inferconfig file @@ -3675,9 +3671,9 @@

    FILES current directory, then its parent, etc., stopping at the first .inferconfig file found.

    -

    Example:

    +

    Example:

    -

    {
    +

    {
    "cxx": false,
    "infer-block-list-files-containing": ["@gen","/* no infer */"]
    @@ -3689,7 +3685,7 @@

    SEE ALSO -

    infer-analyze(1), +

    infer-analyze(1), infer-capture(1), infer-compile(1), infer-debug(1), infer-explore(1), infer-help(1), infer-report(1), diff --git a/odoc/next/infer/Absint/AbstractDomain/NodeSet/index.html b/odoc/next/infer/Absint/AbstractDomain/NodeSet/index.html new file mode 100644 index 00000000000..06aeef7ede8 --- /dev/null +++ b/odoc/next/infer/Absint/AbstractDomain/NodeSet/index.html @@ -0,0 +1,6 @@ + +NodeSet (infer.Absint.AbstractDomain.NodeSet)

    Module AbstractDomain.NodeSet

    include IStdlib.PrettyPrintable.PPSet + with type elt = IR.Procdesc.Node.t + with type t = IR.Procdesc.NodeSet.t
    include Stdlib.Set.S + with type elt = IR.Procdesc.Node.t + with type t = IR.Procdesc.NodeSet.t
    val empty : t
    val add : elt -> t -> t
    val singleton : elt -> t
    val remove : elt -> t -> t
    val union : t -> t -> t
    val inter : t -> t -> t
    val disjoint : t -> t -> bool
    val diff : t -> t -> t
    val cardinal : t -> int
    val elements : t -> elt list
    val min_elt : t -> elt
    val min_elt_opt : t -> elt option
    val max_elt : t -> elt
    val max_elt_opt : t -> elt option
    val choose : t -> elt
    val choose_opt : t -> elt option
    val find : elt -> t -> elt
    val find_opt : elt -> t -> elt option
    val find_first : (elt -> bool) -> t -> elt
    val find_first_opt : (elt -> bool) -> t -> elt option
    val find_last : (elt -> bool) -> t -> elt
    val find_last_opt : (elt -> bool) -> t -> elt option
    val iter : (elt -> unit) -> t -> unit
    val fold : (elt -> 'acc -> 'acc) -> t -> 'acc -> 'acc
    val map : (elt -> elt) -> t -> t
    val filter : (elt -> bool) -> t -> t
    val filter_map : (elt -> elt option) -> t -> t
    val partition : (elt -> bool) -> t -> t * t
    val split : elt -> t -> t * bool * t
    val is_empty : t -> bool
    val mem : elt -> t -> bool
    val equal : t -> t -> bool
    val compare : t -> t -> int
    val subset : t -> t -> bool
    val for_all : (elt -> bool) -> t -> bool
    val exists : (elt -> bool) -> t -> bool
    val to_list : t -> elt list
    val of_list : elt list -> t
    val to_seq_from : elt -> t -> elt Stdlib.Seq.t
    val to_seq : t -> elt Stdlib.Seq.t
    val to_rev_seq : t -> elt Stdlib.Seq.t
    val add_seq : elt Stdlib.Seq.t -> t -> t
    val of_seq : elt Stdlib.Seq.t -> t
    val is_singleton_or_more : t -> elt IStdlib.IContainer.singleton_or_more
    val pp_hov : IStdlib.PrettyPrintable.F.formatter -> t -> unit
    val pp_element : IStdlib.PrettyPrintable.F.formatter -> elt -> unit
    include WithBottom with type t := t
    include S with type t := t
    include Comparable with type t := t
    include IStdlib.PrettyPrintable.PrintableType with type t := t
    val pp : IStdlib.PrettyPrintable.F.formatter -> t -> unit
    val leq : lhs:t -> rhs:t -> bool

    the implication relation: lhs <= rhs means lhs |- rhs

    val join : t -> t -> t
    val widen : prev:t -> next:t -> num_iters:int -> t
    val bottom : t

    The bottom value of the domain.

    val is_bottom : t -> bool

    Return true if this is the bottom value

    diff --git a/odoc/next/infer/Absint/AbstractDomain/module-type-NodeSetS/index.html b/odoc/next/infer/Absint/AbstractDomain/module-type-NodeSetS/index.html new file mode 100644 index 00000000000..9d0df8d5863 --- /dev/null +++ b/odoc/next/infer/Absint/AbstractDomain/module-type-NodeSetS/index.html @@ -0,0 +1,6 @@ + +NodeSetS (infer.Absint.AbstractDomain.NodeSetS)

    Module type AbstractDomain.NodeSetS

    include IStdlib.PrettyPrintable.PPSet + with type elt = IR.Procdesc.Node.t + with type t = IR.Procdesc.NodeSet.t
    include Stdlib.Set.S + with type elt = IR.Procdesc.Node.t + with type t = IR.Procdesc.NodeSet.t
    val empty : t
    val add : elt -> t -> t
    val singleton : elt -> t
    val remove : elt -> t -> t
    val union : t -> t -> t
    val inter : t -> t -> t
    val disjoint : t -> t -> bool
    val diff : t -> t -> t
    val cardinal : t -> int
    val elements : t -> elt list
    val min_elt : t -> elt
    val min_elt_opt : t -> elt option
    val max_elt : t -> elt
    val max_elt_opt : t -> elt option
    val choose : t -> elt
    val choose_opt : t -> elt option
    val find : elt -> t -> elt
    val find_opt : elt -> t -> elt option
    val find_first : (elt -> bool) -> t -> elt
    val find_first_opt : (elt -> bool) -> t -> elt option
    val find_last : (elt -> bool) -> t -> elt
    val find_last_opt : (elt -> bool) -> t -> elt option
    val iter : (elt -> unit) -> t -> unit
    val fold : (elt -> 'acc -> 'acc) -> t -> 'acc -> 'acc
    val map : (elt -> elt) -> t -> t
    val filter : (elt -> bool) -> t -> t
    val filter_map : (elt -> elt option) -> t -> t
    val partition : (elt -> bool) -> t -> t * t
    val split : elt -> t -> t * bool * t
    val is_empty : t -> bool
    val mem : elt -> t -> bool
    val equal : t -> t -> bool
    val compare : t -> t -> int
    val subset : t -> t -> bool
    val for_all : (elt -> bool) -> t -> bool
    val exists : (elt -> bool) -> t -> bool
    val to_list : t -> elt list
    val of_list : elt list -> t
    val to_seq_from : elt -> t -> elt Stdlib.Seq.t
    val to_seq : t -> elt Stdlib.Seq.t
    val to_rev_seq : t -> elt Stdlib.Seq.t
    val add_seq : elt Stdlib.Seq.t -> t -> t
    val of_seq : elt Stdlib.Seq.t -> t
    val is_singleton_or_more : t -> elt IStdlib.IContainer.singleton_or_more
    val pp_hov : IStdlib.PrettyPrintable.F.formatter -> t -> unit
    val pp_element : IStdlib.PrettyPrintable.F.formatter -> elt -> unit
    include WithBottom with type t := t
    include S with type t := t
    include Comparable with type t := t
    include IStdlib.PrettyPrintable.PrintableType with type t := t
    val pp : IStdlib.PrettyPrintable.F.formatter -> t -> unit
    val leq : lhs:t -> rhs:t -> bool

    the implication relation: lhs <= rhs means lhs |- rhs

    val join : t -> t -> t
    val widen : prev:t -> next:t -> num_iters:int -> t
    val bottom : t

    The bottom value of the domain.

    val is_bottom : t -> bool

    Return true if this is the bottom value

    diff --git a/odoc/next/infer/Absint/RecursiveCycleException/index.html b/odoc/next/infer/Absint/RecursiveCycleException/index.html new file mode 100644 index 00000000000..a060c6d8c6c --- /dev/null +++ b/odoc/next/infer/Absint/RecursiveCycleException/index.html @@ -0,0 +1,2 @@ + +RecursiveCycleException (infer.Absint.RecursiveCycleException)

    Module Absint.RecursiveCycleException

    exception RecursiveCycle of {
    1. recursive : IR.SpecializedProcname.t;
    2. ttl : int;
    }
    diff --git a/odoc/next/infer/Backend/GCStats/index.html b/odoc/next/infer/Backend/GCStats/index.html index b17dec5b095..8f70cf9db55 100644 --- a/odoc/next/infer/Backend/GCStats/index.html +++ b/odoc/next/infer/Backend/GCStats/index.html @@ -1,2 +1,2 @@ -GCStats (infer.Backend.GCStats)

    Module Backend.GCStats

    module L = IBase.Logging
    type t
    type since =
    1. | ProgramStart
      (*

      get GC stats from the beginning of the program

      *)
    2. | PreviousStats of t
      (*

      get GC stats relative to another point in time where GC stats were obtained with get ~since:ProgramStart

      *)
    val get : since:since -> t
    val log : name:string -> L.debug_kind -> t -> unit

    log to infer's log file and to Scuba

    val log_aggregate : prefix:string -> L.debug_kind -> t list -> unit

    log aggregate to infer's log file and to Scuba

    val log_f : name:string -> L.debug_kind -> (unit -> 'a) -> 'a

    log GC stats for the duration of the function passed as argument to infer's log file and to Scuba

    +GCStats (infer.Backend.GCStats)

    Module Backend.GCStats

    module L = IBase.Logging
    type t
    type since =
    1. | ProgramStart
      (*

      get GC stats from the beginning of the program

      *)
    2. | PreviousStats of t
      (*

      get GC stats relative to another point in time where GC stats were obtained with get ~since:ProgramStart

      *)
    val get : since:since -> t
    val log : name:string -> L.debug_kind -> t -> unit

    log to infer's log file and to stats

    val log_aggregate : prefix:string -> L.debug_kind -> t list -> unit

    log aggregate to infer's log file and to stats

    val log_f : name:string -> L.debug_kind -> (unit -> 'a) -> 'a

    log GC stats for the duration of the function passed as argument to infer's log file and to stats

    diff --git a/odoc/next/infer/Backend/Ondemand/index.html b/odoc/next/infer/Backend/Ondemand/index.html index a5e4da84a29..b751168e720 100644 --- a/odoc/next/infer/Backend/Ondemand/index.html +++ b/odoc/next/infer/Backend/Ondemand/index.html @@ -19,4 +19,4 @@ specialization:IR.Specialization.t option -> IR.Procname.t -> unit

    Invoke all the callbacks registered in Callbacks on the given procedure.

    used by the replay analysis to cut mutual recursion cycles in the same places again

    + IR.Procname.Set.t IR.Procname.Map.t option IStdlib.IStd.DLS.key

    used by the replay analysis to cut mutual recursion cycles in the same places again

    diff --git a/odoc/next/infer/Checkers/StaticConstructorStallChecker/Mem/index.html b/odoc/next/infer/Checkers/StaticConstructorStallChecker/Mem/index.html new file mode 100644 index 00000000000..690a6e3191f --- /dev/null +++ b/odoc/next/infer/Checkers/StaticConstructorStallChecker/Mem/index.html @@ -0,0 +1,2 @@ + +Mem (infer.Checkers.StaticConstructorStallChecker.Mem)

    Module StaticConstructorStallChecker.Mem

    type kind = [
    1. | `Call
    2. | `Dispatch_once
    ]
    val compare_kind : kind -> kind -> int
    val equal_kind : kind -> kind -> bool
    type trace_elem = {
    1. call_site : Absint.CallSite.t;
    2. kind : kind;
    }
    val compare_trace_elem : trace_elem -> trace_elem -> int
    val equal_trace_elem : trace_elem -> trace_elem -> bool
    type t = trace_elem list
    include Ppx_compare_lib.Comparable.S with type t := t
    include Ppx_compare_lib.Equal.S with type t := t
    val equal : t Base__Ppx_compare_lib.equal
    val compare : t -> t -> int
    val pp : F.formatter -> t -> unit
    diff --git a/odoc/next/infer/Checkers/StaticConstructorStallChecker/Summary/index.html b/odoc/next/infer/Checkers/StaticConstructorStallChecker/Summary/index.html new file mode 100644 index 00000000000..6b99fa8c248 --- /dev/null +++ b/odoc/next/infer/Checkers/StaticConstructorStallChecker/Summary/index.html @@ -0,0 +1,2 @@ + +Summary (infer.Checkers.StaticConstructorStallChecker.Summary)

    Module StaticConstructorStallChecker.Summary

    type elt = Mem.t
    type t
    val empty : t
    val add : elt -> t -> t
    val singleton : elt -> t
    val remove : elt -> t -> t
    val union : t -> t -> t
    val inter : t -> t -> t
    val disjoint : t -> t -> bool
    val diff : t -> t -> t
    val cardinal : t -> int
    val elements : t -> elt list
    val min_elt : t -> elt
    val min_elt_opt : t -> elt option
    val max_elt : t -> elt
    val max_elt_opt : t -> elt option
    val choose : t -> elt
    val choose_opt : t -> elt option
    val find : elt -> t -> elt
    val find_opt : elt -> t -> elt option
    val find_first : (elt -> bool) -> t -> elt
    val find_first_opt : (elt -> bool) -> t -> elt option
    val find_last : (elt -> bool) -> t -> elt
    val find_last_opt : (elt -> bool) -> t -> elt option
    val iter : (elt -> unit) -> t -> unit
    val fold : (elt -> 'acc -> 'acc) -> t -> 'acc -> 'acc
    val map : (elt -> elt) -> t -> t
    val filter : (elt -> bool) -> t -> t
    val filter_map : (elt -> elt option) -> t -> t
    val partition : (elt -> bool) -> t -> t * t
    val split : elt -> t -> t * bool * t
    val is_empty : t -> bool
    val mem : elt -> t -> bool
    val equal : t -> t -> bool
    val compare : t -> t -> int
    val subset : t -> t -> bool
    val for_all : (elt -> bool) -> t -> bool
    val exists : (elt -> bool) -> t -> bool
    val to_list : t -> elt list
    val of_list : elt list -> t
    val to_seq_from : elt -> t -> elt Stdlib.Seq.t
    val to_seq : t -> elt Stdlib.Seq.t
    val to_rev_seq : t -> elt Stdlib.Seq.t
    val add_seq : elt Stdlib.Seq.t -> t -> t
    val of_seq : elt Stdlib.Seq.t -> t
    val is_singleton_or_more : t -> elt IStdlib.IContainer.singleton_or_more
    val pp_hov : IStdlib__PrettyPrintable.F.formatter -> t -> unit
    val pp_element : IStdlib__PrettyPrintable.F.formatter -> elt -> unit
    val pp : IStdlib__PrettyPrintable.F.formatter -> t -> unit
    val leq : lhs:t -> rhs:t -> bool
    val join : t -> t -> t
    val widen : prev:t -> next:t -> num_iters:int -> t
    val bottom : t
    val is_bottom : t -> bool
    diff --git a/odoc/next/infer/Checkers/StaticConstructorStallChecker/index.html b/odoc/next/infer/Checkers/StaticConstructorStallChecker/index.html new file mode 100644 index 00000000000..bd2624a307f --- /dev/null +++ b/odoc/next/infer/Checkers/StaticConstructorStallChecker/index.html @@ -0,0 +1,2 @@ + +StaticConstructorStallChecker (infer.Checkers.StaticConstructorStallChecker)

    Module Checkers.StaticConstructorStallChecker

    module F = Stdlib.Format
    module Mem : sig ... end
    module Summary : sig ... end
    diff --git a/odoc/next/infer/ClangFrontend/CTrans_utils/index.html b/odoc/next/infer/ClangFrontend/CTrans_utils/index.html index 0b14e17a378..af94a9c5b79 100644 --- a/odoc/next/infer/ClangFrontend/CTrans_utils/index.html +++ b/odoc/next/infer/ClangFrontend/CTrans_utils/index.html @@ -1,5 +1,5 @@ -CTrans_utils (infer.ClangFrontend.CTrans_utils)

    Module ClangFrontend.CTrans_utils

    module F = Stdlib.Format

    Utility methods to support the translation of clang ast constructs into sil instructions.

    type continuation = {
    1. break : IR.Procdesc.Node.t list;
    2. continue : IR.Procdesc.Node.t list;
    3. return_temp : bool;
      (*

      true if temps should not be removed in the node but returned to ancestors

      *)
    }
    type priority_node =
    1. | Free
      (*

      no node currently being created

      *)
    2. | Busy of ATDGenerated.Clang_ast_t.pointer
      (*

      the translation of the clang expression or statement at pointer will create a node with the collected instructions from the sub-expressions (see control.instrs

      *)

    Whether we are collecting instructions for a new block in the CFG (Busy) or there are no blocks being created from enclosing translations (Free)

    type trans_state = {
    1. context : CContext.t;
      (*

      global context of the translation

      *)
    2. succ_nodes : IR.Procdesc.Node.t list;
      (*

      successor nodes in the CFG, i.e. instructions that will happen *after* the current expression or statement being translated (note that the CFG is constructed bottom-up, starting from the last instructions)

      *)
    3. continuation : continuation option;
      (*

      current continuation, used for break, continue, and the like

      *)
    4. priority : priority_node;
    5. var_exp_typ : (IR.Exp.t * IR.Typ.t) option;
      (*

      the expression (usually of the form Exp.Lvar pvar) that the enclosing expression or statement is trying to initialize, if any

      *)
    6. opaque_exp : (IR.Exp.t * IR.Typ.t) option;
      (*

      needed for translating OpaqueValueExpr nodes

      *)
    7. is_fst_arg_objc_instance_method_call : bool;
    8. block_as_arg_attributes : IR.ProcAttributes.block_as_arg_attributes option;
    }

    The input of the translation constructed from enclosing expressions.

    val pp_trans_state : F.formatter -> trans_state -> unit
    val default_trans_state : CContext.t -> trans_state
    type control = {
    1. root_nodes : IR.Procdesc.Node.t list;
      (*

      Top cfg nodes (root) created by the translation

      *)
    2. leaf_nodes : IR.Procdesc.Node.t list;
      (*

      Bottom cfg nodes (leaf) created by the translate

      *)
    3. instrs : IR.Sil.instr list;
      (*

      Instructions that need to be placed in the current CFG node being constructed, *after* leaf_nodes.

      *)
    4. initd_exps : IR.Exp.t list;
      (*

      list of expressions that are initialized by the instructions

      *)
    5. cxx_temporary_markers_set : IR.Pvar.t list;
      (*

      markers for C++ temporaries that have been set during the translation; used to avoid adding the same marker several times

      *)
    }

    Part of the translation result that is (loosely) related to control flow graph construction. More importantly, this is the part of a trans_result that some internal translation functions work on when constructing a trans_result before the other components of the translation result are available (such as the return expression). This is made into a separate type to make intermediate computations easier to write and easier to typecheck.

    val pp_control : F.formatter -> control -> unit
    type trans_result = {
    1. control : control;
    2. return : IR.Exp.t * IR.Typ.t;
      (*

      value returned by the translated statement

      *)
    3. method_name : IR.Procname.t option;
      (*

      in the specific case of translating a method call in C++, we get the method name called at the same time we get the this object that contains the method. The this instance object is returned as the return field, while the method to call is filled in here. This field is None in all other cases.

      *)
    4. method_signature : CMethodSignature.t option;
      (*

      in the specific case of translating a function call, we get the method signature. This field is None in all other cases.

      *)
    5. is_cpp_call_virtual : bool;
    }

    A translation result. It is returned by the translation function.

    val empty_control : control
    val mk_trans_result : +CTrans_utils (infer.ClangFrontend.CTrans_utils)

    Module ClangFrontend.CTrans_utils

    module F = Stdlib.Format

    Utility methods to support the translation of clang ast constructs into sil instructions.

    type continuation = {
    1. break : IR.Procdesc.Node.t list;
    2. continue : IR.Procdesc.Node.t list;
    3. return_temp : bool;
      (*

      true if temps should not be removed in the node but returned to ancestors

      *)
    }
    type priority_node =
    1. | Free
      (*

      no node currently being created

      *)
    2. | Busy of ATDGenerated.Clang_ast_t.pointer
      (*

      the translation of the clang expression or statement at pointer will create a node with the collected instructions from the sub-expressions (see control.instrs

      *)

    Whether we are collecting instructions for a new block in the CFG (Busy) or there are no blocks being created from enclosing translations (Free)

    type trans_state = {
    1. context : CContext.t;
      (*

      global context of the translation

      *)
    2. succ_nodes : IR.Procdesc.Node.t list;
      (*

      successor nodes in the CFG, i.e. instructions that will happen *after* the current expression or statement being translated (note that the CFG is constructed bottom-up, starting from the last instructions)

      *)
    3. continuation : continuation option;
      (*

      current continuation, used for break, continue, and the like

      *)
    4. priority : priority_node;
    5. var_exp_typ : (IR.Exp.t * IR.Typ.t) option;
      (*

      the expression (usually of the form Exp.Lvar pvar) that the enclosing expression or statement is trying to initialize, if any

      *)
    6. opaque_exp : (IR.Exp.t * IR.Typ.t) option;
      (*

      needed for translating OpaqueValueExpr nodes

      *)
    7. is_objc_getter_setter_call : bool;
    8. is_fst_arg_objc_instance_method_call : bool;
    9. block_as_arg_attributes : IR.ProcAttributes.block_as_arg_attributes option;
    }

    The input of the translation constructed from enclosing expressions.

    val pp_trans_state : F.formatter -> trans_state -> unit
    val default_trans_state : CContext.t -> trans_state
    type control = {
    1. root_nodes : IR.Procdesc.Node.t list;
      (*

      Top cfg nodes (root) created by the translation

      *)
    2. leaf_nodes : IR.Procdesc.Node.t list;
      (*

      Bottom cfg nodes (leaf) created by the translate

      *)
    3. instrs : IR.Sil.instr list;
      (*

      Instructions that need to be placed in the current CFG node being constructed, *after* leaf_nodes.

      *)
    4. initd_exps : IR.Exp.t list;
      (*

      list of expressions that are initialized by the instructions

      *)
    5. cxx_temporary_markers_set : IR.Pvar.t list;
      (*

      markers for C++ temporaries that have been set during the translation; used to avoid adding the same marker several times

      *)
    }

    Part of the translation result that is (loosely) related to control flow graph construction. More importantly, this is the part of a trans_result that some internal translation functions work on when constructing a trans_result before the other components of the translation result are available (such as the return expression). This is made into a separate type to make intermediate computations easier to write and easier to typecheck.

    val pp_control : F.formatter -> control -> unit
    type trans_result = {
    1. control : control;
    2. return : IR.Exp.t * IR.Typ.t;
      (*

      value returned by the translated statement

      *)
    3. method_name : IR.Procname.t option;
      (*

      in the specific case of translating a method call in C++, we get the method name called at the same time we get the this object that contains the method. The this instance object is returned as the return field, while the method to call is filled in here. This field is None in all other cases.

      *)
    4. method_signature : CMethodSignature.t option;
      (*

      in the specific case of translating a function call, we get the method signature. This field is None in all other cases.

      *)
    5. is_cpp_call_virtual : bool;
    }

    A translation result. It is returned by the translation function.

    val empty_control : control
    val mk_trans_result : ?method_name:IR.Procname.t -> ?method_signature:CMethodSignature.t -> ?is_cpp_call_virtual:bool -> diff --git a/odoc/next/infer/Concurrency/StarvationDomain/ThreadDomain/index.html b/odoc/next/infer/Concurrency/StarvationDomain/ThreadDomain/index.html index 1258019043d..b8979a1f08b 100644 --- a/odoc/next/infer/Concurrency/StarvationDomain/ThreadDomain/index.html +++ b/odoc/next/infer/Concurrency/StarvationDomain/ThreadDomain/index.html @@ -1,2 +1,2 @@ -ThreadDomain (infer.Concurrency.StarvationDomain.ThreadDomain)

    Module StarvationDomain.ThreadDomain

    Domain for thread-type. The main goals are

    • Track code paths that are explicitly on UI/BG thread (via annotations, or assertions).
    • Maintain UI/BG-thread-ness through the call stack (if a caller is of unknown status and callee is on UI/BG thread then caller must be on the UI/BG thread too).
    • Traces with "UI-thread" status cannot interleave but all other combinations can.
    • Top is AnyThread, which means that there are executions on both UI and BG threads on this method.
    • Bottom is UnknownThread, and used as initial state.
    type t =
    1. | UnknownThread
    2. | UIThread
    3. | BGThread
    4. | AnyThread
    5. | NamedThread of string
    include Absint.AbstractDomain.WithBottom with type t := t
    include Absint.AbstractDomain.S with type t := t
    include Absint.AbstractDomain.Comparable with type t := t
    include IStdlib.PrettyPrintable.PrintableType with type t := t
    val pp : IStdlib.PrettyPrintable.F.formatter -> t -> unit
    val leq : lhs:t -> rhs:t -> bool

    the implication relation: lhs <= rhs means lhs |- rhs

    val join : t -> t -> t
    val widen : prev:t -> next:t -> num_iters:int -> t
    val bottom : t

    The bottom value of the domain.

    val is_bottom : t -> bool

    Return true if this is the bottom value

    +ThreadDomain (infer.Concurrency.StarvationDomain.ThreadDomain)

    Module StarvationDomain.ThreadDomain

    Domain for thread-type. The main goals are

    • Track code paths that are explicitly on UI/BG thread (via annotations, or assertions).
    • Maintain UI/BG-thread-ness through the call stack (if a caller is of unknown status and callee is on UI/BG thread then caller must be on the UI/BG thread too).
    • Traces with "UI-thread" status cannot interleave but all other combinations can.
    • Top is AnyThread, which means that there are executions on both UI and BG threads on this method.
    • Bottom is UnknownThread, and used as initial state.
    type t =
    1. | UnknownThread
    2. | UIThread
    3. | BGThread
    4. | AnyThread
    5. | NamedThread of string
    val is_uithread : t -> bool
    include Absint.AbstractDomain.WithBottom with type t := t
    include Absint.AbstractDomain.S with type t := t
    include Absint.AbstractDomain.Comparable with type t := t
    include IStdlib.PrettyPrintable.PrintableType with type t := t
    val pp : IStdlib.PrettyPrintable.F.formatter -> t -> unit
    val leq : lhs:t -> rhs:t -> bool

    the implication relation: lhs <= rhs means lhs |- rhs

    val join : t -> t -> t
    val widen : prev:t -> next:t -> num_iters:int -> t
    val bottom : t

    The bottom value of the domain.

    val is_bottom : t -> bool

    Return true if this is the bottom value

    diff --git a/odoc/next/infer/IBase/AnalysisRequest/index.html b/odoc/next/infer/IBase/AnalysisRequest/index.html index 9f258a7c7b4..c6f8583fb1a 100644 --- a/odoc/next/infer/IBase/AnalysisRequest/index.html +++ b/odoc/next/infer/IBase/AnalysisRequest/index.html @@ -1,2 +1,2 @@ -AnalysisRequest (infer.IBase.AnalysisRequest)

    Module IBase.AnalysisRequest

    type checker_without_payload =
    1. | LoopHoisting
    type t = private
    1. | All
      (*

      Request the analyses for all payloads enabled

      *)
    2. | One of PayloadId.t
      (*

      Request an analysis for one payload

      *)
    3. | CheckerWithoutPayload of checker_without_payload
      (*

      Request an analysis of a checker that has no payload in DB

      *)

    This is given to the callback iteration, so that only a subset of them are triggered when necessary.

    include Ppx_compare_lib.Equal.S with type t := t
    val equal : t Base__Ppx_compare_lib.equal
    include Ppx_hash_lib.Hashable.S with type t := t
    val hash_fold_t : t Base__Ppx_hash_lib.hash_fold
    val hash : t -> Base__Ppx_hash_lib.Std.Hash.hash_value
    val pp : Ppx_show_runtime.Format.formatter -> t -> unit
    val show : t -> string
    val all : t
    val one : PayloadId.t -> t
    val checker_without_payload : checker_without_payload -> t
    +AnalysisRequest (infer.IBase.AnalysisRequest)

    Module IBase.AnalysisRequest

    type checker_without_payload =
    1. | LoopHoisting
    type t = private
    1. | All
      (*

      Request the analyses for all payloads enabled

      *)
    2. | One of PayloadId.t
      (*

      Request an analysis for one payload

      *)
    3. | CheckerWithoutPayload of checker_without_payload
      (*

      Request an analysis of a checker that has no payload in DB

      *)

    This is given to the callback iteration, so that only a subset of them are triggered when necessary.

    include Ppx_compare_lib.Comparable.S with type t := t
    val compare : t Base__Ppx_compare_lib.compare
    include Ppx_compare_lib.Equal.S with type t := t
    val equal : t Base__Ppx_compare_lib.equal
    include Ppx_hash_lib.Hashable.S with type t := t
    val hash_fold_t : t Base__Ppx_hash_lib.hash_fold
    val hash : t -> Base__Ppx_hash_lib.Std.Hash.hash_value
    val pp : Ppx_show_runtime.Format.formatter -> t -> unit
    val show : t -> string
    val all : t
    val one : PayloadId.t -> t
    val checker_without_payload : checker_without_payload -> t
    diff --git a/odoc/next/infer/IBase/Config/index.html b/odoc/next/infer/IBase/Config/index.html index da38e4d1f58..a3bc256dda3 100644 --- a/odoc/next/infer/IBase/Config/index.html +++ b/odoc/next/infer/IBase/Config/index.html @@ -1,12 +1,10 @@ -Config (infer.IBase.Config)

    Module IBase.Config

    Configuration values: either constant, determined at compile time, or set at startup time by system calls, environment variables, or command line options

    type os_type =
    1. | Unix
    2. | Win32
    3. | Cygwin
    type build_system =
    1. | BAnt
    2. | BBuck
    3. | BBuck2
    4. | BClang
    5. | BErlc
    6. | BGradle
    7. | BHackc
    8. | BJava
    9. | BJavac
    10. | BKotlinc
    11. | BMake
    12. | BMvn
    13. | BNdk
    14. | BPython
    15. | BRebar3
    16. | BXcode
    type scheduler =
    1. | File
    2. | Restart
    3. | SyntacticCallGraph
    val equal_scheduler : scheduler -> scheduler -> bool
    val string_of_scheduler : scheduler -> string
    type python_globals =
    1. | OwnByClosures
    2. | OwnByModule
    val equal_python_globals : python_globals -> python_globals -> bool
    val build_system_of_exe_name : string -> build_system
    val string_of_build_system : build_system -> string
    val env_inside_maven : IStdlib.IStd.Unix.env

    Constant configuration values

    val allow_listed_cpp_classes : string list
    val allow_listed_cpp_methods : string list
    val anonymous_block_prefix : string
    val biabduction_models_jar : string
    val biabduction_models_sql : string
    val bin_dir : string
    val bound_error_allowed_in_procedure_call : bool
    val clang_exe_aliases : string list
    val clang_initializer_prefix : string
    val clang_inner_destructor_prefix : string
    val clang_plugin_path : string
    val default_failure_name : string
    val dotty_frontend_output : string
    val etc_dir : string
    val fail_on_issue_exit_code : int
    val fcp_dir : string
    val idempotent_getters : bool
    val initial_analysis_time : float
    val is_running_unit_test : bool

    whether the infer executable looks like we are just running infer unit tests

    val java_lambda_marker_infix_generated_by_javalib : string

    marker to recognize methods generated by javalib to eliminate lambdas

    val java_lambda_marker_prefix_generated_by_javac : string

    marker to recognize methods generated by javac to build closures

    val kotlin_source_extension : string
    val lib_dir : string
    val max_narrows : int
    val max_widens : int
    val meet_level : int
    val nsnotification_center_checker_backend : bool
    val os_type : os_type
    val pp_version : Stdlib.Format.formatter -> unit -> unit
    val report_nullable_inconsistency : bool
    val save_compact_summaries : bool
    val smt_output : bool
    val wrappers_dir : string

    Configuration values specified by command-line options

    val abstract_pulse_models_for_erlang : bool
    val analysis_schedule_file : string option
    val annotation_reachability_apply_superclass_annotations : bool
    val annotation_reachability_check_loops : bool
    val annotation_reachability_custom_models : Yojson.Safe.t
    val annotation_reachability_custom_pairs : Yojson.Safe.t
    val annotation_reachability_expensive : bool
    val annotation_reachability_minimize_sinks : bool
    val annotation_reachability_minimize_sources : bool
    val annotation_reachability_no_allocation : bool
    val annotation_reachability_report_source_and_sink : bool
    val append_buck_flavors : string list
    val biabduction_abs_struct : int
    val biabduction_abs_val : int
    val biabduction_allow_leak : bool
    val biabduction_array_level : int
    val biabduction_iterations : int
    val biabduction_join_cond : int
    val biabduction_memleak_buckets : +Config (infer.IBase.Config)

    Module IBase.Config

    Configuration values: either constant, determined at compile time, or set at startup time by system calls, environment variables, or command line options

    type os_type =
    1. | Unix
    2. | Win32
    3. | Cygwin
    type build_system =
    1. | BAnt
    2. | BBuck
    3. | BBuck2
    4. | BClang
    5. | BErlc
    6. | BGradle
    7. | BHackc
    8. | BJava
    9. | BJavac
    10. | BKotlinc
    11. | BMake
    12. | BMvn
    13. | BNdk
    14. | BPython
    15. | BRebar3
    16. | BXcode
    type scheduler =
    1. | File
    2. | Restart
    3. | SyntacticCallGraph
    val equal_scheduler : scheduler -> scheduler -> bool
    val string_of_scheduler : scheduler -> string
    val build_system_of_exe_name : string -> build_system
    val string_of_build_system : build_system -> string
    val env_inside_maven : IStdlib.IStd.Unix.env

    Constant configuration values

    val allow_listed_cpp_classes : string list
    val allow_listed_cpp_methods : string list
    val anonymous_block_prefix : string
    val biabduction_models_jar : string
    val biabduction_models_sql : string
    val bin_dir : string
    val bound_error_allowed_in_procedure_call : bool
    val clang_exe_aliases : string list
    val clang_initializer_prefix : string
    val clang_inner_destructor_prefix : string
    val clang_plugin_path : string
    val default_failure_name : string
    val dotty_frontend_output : string
    val etc_dir : string
    val fail_on_issue_exit_code : int
    val fcp_dir : string
    val idempotent_getters : bool
    val initial_analysis_time : float
    val is_running_unit_test : bool

    whether the infer executable looks like we are just running infer unit tests

    val java_lambda_marker_infix_generated_by_javalib : string

    marker to recognize methods generated by javalib to eliminate lambdas

    val java_lambda_marker_prefix_generated_by_javac : string

    marker to recognize methods generated by javac to build closures

    val kotlin_source_extension : string
    val lib_dir : string
    val max_narrows : int
    val max_widens : int
    val meet_level : int
    val nsnotification_center_checker_backend : bool
    val os_type : os_type
    val pp_version : Stdlib.Format.formatter -> unit -> unit
    val report_nullable_inconsistency : bool
    val save_compact_summaries : bool
    val smt_output : bool
    val wrappers_dir : string

    Configuration values specified by command-line options

    val abstract_pulse_models_for_erlang : bool
    val analysis_schedule_file : string option
    val annotation_reachability_apply_superclass_annotations : bool
    val annotation_reachability_check_loops : bool
    val annotation_reachability_custom_models : Yojson.Safe.t
    val annotation_reachability_custom_pairs : Yojson.Safe.t
    val annotation_reachability_expensive : bool
    val annotation_reachability_minimize_sinks : bool
    val annotation_reachability_minimize_sources : bool
    val annotation_reachability_no_allocation : bool
    val annotation_reachability_report_source_and_sink : bool
    val append_buck_flavors : string list
    val biabduction_abs_struct : int
    val biabduction_abs_val : int
    val biabduction_allow_leak : bool
    val biabduction_array_level : int
    val biabduction_iterations : int
    val biabduction_join_cond : int
    val biabduction_memleak_buckets : [ `MLeak_all | `MLeak_arc | `MLeak_cf | `MLeak_cpp | `MLeak_no_arc | `MLeak_unknown ] - list
    val biabduction_models_mode : bool
    val biabduction_monitor_prop_size : bool
    val biabduction_nelseg : bool
    val biabduction_only_footprint : bool
    val biabduction_seconds_per_iteration : float option
    val biabduction_symops_per_iteration : int option
    val biabduction_trace_join : bool
    val biabduction_trace_rearrange : bool
    val biabduction_type_size : bool
    val biabduction_unsafe_malloc : bool
    val biabduction_worklist_mode : int
    val biabduction_write_dotty : bool
    val bo_assume_void : bool
    val bo_bottom_as_default : bool
    val bo_context_sensitive_allocsites : bool
    val bo_debug : int
    val bo_exit_frontend_gener_vars : bool
    val bo_field_depth_limit : int option
    val bo_max_cfg_size : int
    val bo_sound_unknown_sets_join : bool
    val bootclasspath : string option
    val buck : bool
    val buck2_build_args : string list
    val buck2_build_args_no_inline : string list
    val buck2_bxl_capture_file_block_list : string list
    val buck2_bxl_target : string option
    val buck2_inferconfig_target : string option
    val buck2_infertoolchain_target : string option
    val buck2_isolation_dir : string option
    val buck2_query_deps : bool
    val buck2_root : string
    val buck_block_list : string list
    val buck_build_args : string list
    val buck_build_args_no_inline : string list
    val buck_cache_mode : bool
    val buck_clang_use_toolchain_config : bool
    val buck_dependency_depth : int option
    val buck_java_heap_size_gb : int option
    val buck_java_suppress_config : bool
    val buck_merge_all_deps : bool
    val buck_mode : BuckMode.t option
    val buck_out : string
    val buck_out_gen : string
    val buck_targets_block_list : string list
    val capture : bool
    val capture_block_list : string * Yojson.Safe.t
    val capture_textual : string list
    val censor_report : - ((bool * IStdlib.IStd.Str.regexp) * (bool * IStdlib.IStd.Str.regexp) * string) - list
    val cfg_json : string option
    val changed_files_index : string option
    val check_version : string option
    val clang_ast_file : [ `Biniou of string | `Yojson of string ] option
    val clang_block_listed_flags : string list
    val clang_block_listed_flags_with_arg : string list
    val clang_compound_literal_init_limit : int
    val clang_extra_flags : string list
    val clang_frontend_action_string : string
    val clang_idirafter_to_override_regex : IStdlib.IStd.Str.regexp option
    val clang_ignore_regex : IStdlib.IStd.Str.regexp option
    val clang_isystem_to_override_regex : IStdlib.IStd.Str.regexp option
    val clang_libcxx_include_to_override_regex : string option
    val classpath : string option
    val compaction_if_heap_greater_equal_to_GB : int
    val compaction_minimum_interval_s : int
    val complete_capture_from : string option
    val compute_captured_context : bool
    val config_impact_config_field_patterns : IStdlib.IStd.Str.regexp list
    val config_impact_config_function_patterns : IStdlib.IStd.Str.regexp list
    val config_impact_config_param_patterns : IStdlib.IStd.Str.regexp list
    val config_impact_current : string option
    val config_impact_data_file : string option
    val config_impact_issues_tests : string option
    val config_impact_max_callees_to_print : int
    val config_impact_previous : string option
    val config_impact_strict_mode : bool
    val config_impact_strict_mode_paths : IStdlib.IStd.Str.regexp list
    val config_impact_test_paths : IStdlib.IStd.Str.regexp list
    val continue_analysis : bool
    val continue_capture : bool
    val cost_issues_tests : string option
    val cost_log_unknown_calls : bool
    val cost_suppress_func_ptr : bool
    val costs_current : string option
    val costs_previous : string option
    val cxx : bool
    val cxx_scope_guards : Yojson.Safe.t
    val data_flow_queries_on_topl : string list
    val dbwriter : bool
    val debug_exceptions : bool
    val debug_level_analysis : int
    val debug_level_capture : int
    val debug_level_report : int
    val debug_mode : bool
    val deduplicate : bool
    val default_hack_builtin_models_rel : string
    val dependency_mode : bool
    val detach_analysis_dependency : bool
    val developer_mode : bool
    val dict_missing_key_var_block_list : IStdlib.IStd.Str.regexp option
    val differential_filter_files : string option
    val differential_filter_set : [ `Introduced | `Fixed | `Preexisting ] list
    val dotty_cfg_libs : bool
    val dump_duplicate_symbols : bool
    val dump_textual : bool
    val dynamic_dispatch_json_file_path : string option
    val erlang_ast_dir : string option
    val erlang_check_return : bool
    val erlang_list_unfold_depth : int
    val erlang_reliability : bool
    val erlang_skip_compile : bool
    val erlang_with_otp_specs : bool
    val extract_capture_from : string option
    val fail_on_bug : bool
    val fcp_apple_clang : string option
    val fcp_syntax_only : bool
    val file_renamings : string option
    val files_to_analyze_index : string option
    val filter_paths : bool
    val filtering : bool
    val force_delete_results_dir : bool
    val force_integration : build_system option
    val from_json_config_impact_report : string
    val from_json_costs_report : string
    val from_json_report : string
    val frontend_stats : bool
    val frontend_tests : bool
    val generated_classes : string option
    val genrule_mode : bool
    val global_tenv : bool
    val hackc_binary : string option
    type pulse_hack_builder_pattern = {
    1. class_name : string;
    2. finalizers : string list;
    3. immediately_non_discardable_class : string option;
    }
    type pulse_hack_builder_patterns = pulse_hack_builder_pattern list
    val hack_builder_patterns : pulse_hack_builder_patterns
    val hack_builtin_models : string
    val hack_models : string list
    val hack_naming_table : string option
    val hack_verify_capture_only : bool
    val help_checker : Checker.t list
    val help_issue_type : IssueType.t list
    val hoisting_report_only_expensive : bool
    val html : bool
    val icfg_dotty_outfile : string option
    val implicit_sdk_root : string option
    val impurity_report_immutable_modifications : bool
    val inclusive_cost : bool
    val incremental_analysis : bool
    val infer_binary : string

    absolute canonicalized path to the current executable

    val infer_is_clang : bool
    val infer_is_javac : bool
    val inferconfig_file : string option
    val inline_func_pointer_for_testing : string option
    val invalidate_only : bool
    val is_checker_enabled : Checker.t -> bool
    val issues_tests : string option
    val issues_tests_fields : IssuesTestField.t list
    val java_debug_source_file_info : string option
    val java_jar_compiler : string option
    val java_read_modules : bool
    val java_source_parser_experimental : bool
    val java_version : int option
    val javac_classes_out : string
    val job_id : string option
    val jobs : int
    val keep_going : bool
    val kotlin_capture : bool
    val lineage_source : string list
    val lineage_sink : string list
    val lineage_sanitizers : string list
    val lineage_limit : int option
    val lineage_dedup : bool
    val lineage_field_depth : int
    val lineage_field_max_cfg_size : int option
    val lineage_field_width : int
    val lineage_include_builtins : bool
    val lineage_json_report : bool
    val lineage_keep_temporaries : bool
    val lineage_max_cfg_size : int option
    val lineage_prevent_cycles : bool
    val lineage_seed : int
    val lineage_variant_width : int
    val list_categories : bool
    val list_checkers : bool
    val list_issue_types : bool
    val liveness_block_list_var_regex : IStdlib.IStd.Str.regexp option
    val liveness_dangerous_classes : Yojson.Safe.t
    val liveness_ignored_constant : string list
    val load_average : float option
    val lock_model : Yojson.Safe.t
    val log_pulse_disjunct_increase_after_model_call : bool
    val log_pulse_coverage : bool
    val log_missing_deps : bool
    val margin_html : int
    val mark_unchanged_procs : bool
    val mask_sajwa_exceptions : bool
    val max_nesting : int option
    val memtrace_analysis : bool
    val memtrace_sampling_rate : float
    val merge_capture : string list
    val merge_report : string list
    val merge_summaries : string list
    val modeled_expensive : string * Yojson.Safe.t
    val never_returning_null : string * Yojson.Safe.t
    val noescaping_function_list : string list
    val no_censor_report : IStdlib.IStd.Str.regexp list
    val no_translate_libs : bool
    val nullable_annotation : string option
    val objc_block_execution_macro : string option
    val objc_synthesize_dealloc : bool
    val ondemand_recursion_restart_limit : int
    val only_cheap_debug : bool
    val oom_threshold : int option
    val pmd_xml : bool
    val preanalysis_html : bool
    val print_active_checkers : bool
    val print_builtins : bool
    val print_jbir : bool
    val print_logs : bool
    val print_types : bool
    val print_using_diff : bool
    val procedures : bool
    val procedures_attributes : bool
    val procedures_call_graph : bool
    val procedures_callees : bool
    val procedures_cfg : bool
    val procedures_definedness : bool
    val procedures_filter : string option
    val procedures_name : bool
    val procedures_source_file : bool
    val procedures_summary : bool
    val procedures_summary_json : bool
    val procedures_summary_skip_empty : bool
    val process_clang_ast : bool
    val procs_to_analyze_index : string option
    val progress_bar : [ `MultiLine | `Plain | `Quiet ]
    val project_root : string
    val pulse_balanced_disjuncts_strategy : bool
    val pulse_cut_to_one_path_procedures_pattern : IStdlib.IStd.Str.regexp option
    val pulse_force_continue : bool
    val pulse_havoc_arguments : bool
    val pulse_inline_global_init_func_pointer : bool
    val pulse_intraprocedural_only : bool
    val pulse_log_summary_count : bool
    val pulse_log_unknown_calls : bool
    val pulse_log_unknown_calls_sampled : int option
    val pulse_max_cfg_size : int
    val pulse_max_disjuncts : int
    val pulse_max_heap : int option
    val pulse_model_abort : string list
    val pulse_model_alloc_pattern : IStdlib.IStd.Str.regexp option
    val pulse_model_cheap_copy_type : IStdlib.IStd.Str.regexp option
    val pulse_model_free_pattern : IStdlib.IStd.Str.regexp option
    val pulse_model_malloc_pattern : IStdlib.IStd.Str.regexp option
    val pulse_model_realloc_pattern : IStdlib.IStd.Str.regexp option
    val pulse_model_release_pattern : IStdlib.IStd.Str.regexp option
    val pulse_model_return_first_arg : IStdlib.IStd.Str.regexp option
    val pulse_model_return_nonnull : IStdlib.IStd.Str.regexp option
    val pulse_model_return_this : IStdlib.IStd.Str.regexp option
    val pulse_model_returns_copy_pattern : IStdlib.IStd.Str.regexp option
    val pulse_model_skip_pattern : IStdlib.IStd.Str.regexp option
    val pulse_model_transfer_ownership : string list
    val pulse_model_transfer_ownership_namespace : (string * string) list
    val pulse_model_unknown_pure : IStdlib.IStd.Str.regexp option
    val pulse_model_unreachable : string list
    val pulse_models_for_erlang : string list
    val pulse_monitor_transitive_callees : bool
    val pulse_monitor_transitive_missed_captures : bool
    val pulse_nullsafe_report_npe : bool
    val pulse_nullsafe_report_npe_as_separate_issue_type : bool
    val pulse_over_approximate_reasoning : bool
    val pulse_prevent_non_disj_top : bool
    val pulse_recency_limit : int
    val pulse_report_flows_from_taint_source : string option
    val pulse_report_flows_to_taint_sink : string option
    val pulse_report_issues_for_tests : bool
    val pulse_report_latent_issues : bool
    val pulse_sanity_checks : bool
    val pulse_skip_procedures : IStdlib.IStd.Str.regexp option
    val pulse_specialization_iteration_limit : int
    val pulse_specialization_limit : int
    val pulse_specialization_partial : bool
    val pulse_taint_config : pulse_taint_config
    val pulse_taint_follow_field_accesses : bool
    val pulse_taint_opaque_files : string list
    val pulse_taint_short_traces : bool
    val pulse_taint_skip_sources : bool
    val pulse_transitive_access_config : string list
    val pulse_transitive_access_enabled : bool
    val pulse_transitive_access_verbose : bool
    val pulse_unsafe_malloc : bool
    val pulse_widen_threshold : int
    val pure_by_default : bool
    val pyc_file : string list
    val python_files_index : string option
    val python_skip_db : bool
    val python_globals : python_globals
    val qualified_cpp_name_block_list : string list
    val quiet : bool
    val racerd_always_report_java : bool
    val racerd_guardedby : bool
    val racerd_ignore_classes : IStdlib.IString.Set.t
    val reactive_mode : bool
    val reactive_capture : bool
    val reanalyze : bool
    val relative_path_backtrack : int
    val replay_analysis_schedule : bool
    val replay_ondemand_should_error : bool
    val report : bool
    val report_block_list_files_containing : string list
    val report_console_limit : int option
    val report_current : string option
    val report_custom_error : bool
    val report_force_relative_path : bool
    val report_formatter : [ `No_formatter | `Phabricator_formatter ]
    val report_path_regex_allow_list : string list
    val report_path_regex_block_list : string list
    val report_previous : string option
    val report_suppress_errors : string list
    val reports_include_ml_loc : bool
    val rest : string list
    val results_dir : string
    val run_as_child : int option
    val run_python_interpreter : bool
    val sarif : bool
    val scheduler : scheduler
    val scope_leakage_config : Yojson.Safe.t
    val scuba_logging : bool
    val scuba_normals : string IStdlib.IStd.String.Map.t
    val scuba_tags : string list IStdlib.IStd.String.Map.t
    val select : [ `All | `Select of int ] option
    val show_buckets : bool
    val shrink_analysis_db : bool
    val siof_check_iostreams : bool
    val siof_safe_methods : string list
    val skip_analysis_in_path : IStdlib.IStd.Str.regexp option
    val skip_analysis_in_path_skips_compilation : bool
    val skip_duplicated_types : bool
    val skip_non_capture_clang_commands : bool
    val skip_translation_headers : string list
    val source_files : bool
    val source_files_call_graph : bool
    val source_files_call_graph_partition : int option
    val source_files_cfg : bool
    val source_files_filter : string option
    val source_files_freshly_captured : bool
    val source_files_procedure_names : bool
    val source_files_type_environment : bool
    val source_preview : bool
    val sourcepath : string option
    val sources : string list
    val sqlite_cache_size : int
    val sqlite_lock_timeout : int
    val sqlite_max_blob_size : int
    val sqlite_mmap_size : int
    val sqlite_page_size : int
    val sqlite_vfs : string option
    val starvation_c_function_pointer_models : Yojson.Safe.t
    val starvation_c_named_threads_annot : Yojson.Safe.t
    val starvation_skip_analysis : Yojson.Safe.t
    val starvation_strict_mode : bool
    val starvation_whole_program : bool
    val stats_dir_current : string option
    val stats_dir_previous : string option
    val struct_as_cpp_class : bool
    val store_analysis_schedule : bool
    val subtype_multirange : bool
    val suffix_match_changed_files : bool
    val summaries_caches_max_size : int
    val suppress_lint_ignore_types : bool
    val suppressions : bool
    val tenv_json : string option
    val testing_mode : bool
    val threadsafe_aliases : Yojson.Safe.t
    val timeout : float option
    val top_longest_proc_duration_size : int option
    val topl_max_conjuncts : int
    val topl_max_disjuncts : int
    val topl_properties : ToplAst.t list
    val topl_report_latent_issues : bool
    val trace_absarray : bool
    val trace_error : bool
    val trace_events : bool
    val trace_ondemand : bool
    val trace_topl : bool
    val unix_fork : bool
    val workspace : string option
    val write_html : bool
    val write_html_allow_list_regex : string list
    val write_website : string option
    val xcode_developer_dir : string option
    val xcode_isysroot_suffix : string option
    val xcpretty : bool

    Configuration values derived from command-line options

    val toplevel_results_dir : string

    In some integrations, eg Buck, infer subprocesses started by the build system (started by the toplevel infer process) will have their own results directory; this points to the results directory of the toplevel infer process, which can be useful for, eg, storing debug info. In other cases this is equal to results_dir.

    val java_package_is_external : string -> bool

    Check if a Java package is external to the repository

    val scuba_execution_id : IStdlib.IStd.Int64.t option

    a random number to (hopefully) uniquely identify this run

    val is_originator : bool

    is the current process (forked from) the root of the Infer process tree

    Global variables with initial values specified by command-line options

    val clang_compilation_dbs : [ `Escaped of string | `Raw of string ] list
    + list
    val biabduction_models_mode : bool
    val biabduction_monitor_prop_size : bool
    val biabduction_nelseg : bool
    val biabduction_only_footprint : bool
    val biabduction_seconds_per_iteration : float option
    val biabduction_symops_per_iteration : int option
    val biabduction_trace_join : bool
    val biabduction_trace_rearrange : bool
    val biabduction_type_size : bool
    val biabduction_unsafe_malloc : bool
    val biabduction_worklist_mode : int
    val biabduction_write_dotty : bool
    val bo_assume_void : bool
    val bo_bottom_as_default : bool
    val bo_context_sensitive_allocsites : bool
    val bo_debug : int
    val bo_exit_frontend_gener_vars : bool
    val bo_field_depth_limit : int option
    val bo_max_cfg_size : int
    val bo_sound_unknown_sets_join : bool
    val bootclasspath : string option
    val buck : bool
    val buck2_build_args : string list
    val buck2_build_args_no_inline : string list
    val buck2_bxl_capture_file_block_list : string list
    val buck2_bxl_target : string option
    val buck2_inferconfig_target : string option
    val buck2_infertoolchain_target : string option
    val buck2_isolation_dir : string option
    val buck2_query_deps : bool
    val buck2_root : string
    val buck_block_list : string list
    val buck_build_args : string list
    val buck_build_args_no_inline : string list
    val buck_cache_mode : bool
    val buck_clang_use_toolchain_config : bool
    val buck_dependency_depth : int option
    val buck_java_heap_size_gb : int option
    val buck_java_suppress_config : bool
    val buck_merge_all_deps : bool
    val buck_mode : BuckMode.t option
    val buck_out : string
    val buck_out_gen : string
    val buck_targets_block_list : string list
    val capture : bool
    val capture_block_list : string * Yojson.Safe.t
    val capture_textual : string list
    val censor_report : ((bool * Str.regexp) * (bool * Str.regexp) * string) list
    val cfg_json : string option
    val changed_files_index : string option
    val check_version : string option
    val clang_ast_file : [ `Biniou of string | `Yojson of string ] option
    val clang_block_listed_flags : string list
    val clang_block_listed_flags_with_arg : string list
    val clang_compound_literal_init_limit : int
    val clang_extra_flags : string list
    val clang_frontend_action_string : string
    val clang_idirafter_to_override_regex : Str.regexp option
    val clang_ignore_regex : Str.regexp option
    val clang_isystem_to_override_regex : Str.regexp option
    val clang_libcxx_include_to_override_regex : string option
    val classpath : string option
    val compaction_if_heap_greater_equal_to_GB : int
    val complete_capture_from : string option
    val compute_captured_context : bool
    val config_impact_config_field_patterns : Str.regexp list
    val config_impact_config_function_patterns : Str.regexp list
    val config_impact_config_param_patterns : Str.regexp list
    val config_impact_current : string option
    val config_impact_data_file : string option
    val config_impact_issues_tests : string option
    val config_impact_max_callees_to_print : int
    val config_impact_previous : string option
    val config_impact_strict_mode : bool
    val config_impact_strict_mode_paths : Str.regexp list
    val config_impact_test_paths : Str.regexp list
    val continue_analysis : bool
    val continue_capture : bool
    val cost_issues_tests : string option
    val cost_log_unknown_calls : bool
    val cost_suppress_func_ptr : bool
    val costs_current : string option
    val costs_previous : string option
    val cxx : bool
    val cxx_scope_guards : Yojson.Safe.t
    val data_flow_queries_on_topl : string list
    val dbwriter : bool
    val debug_exceptions : bool
    val debug_level_analysis : int
    val debug_level_capture : int
    val debug_level_report : int
    val debug_mode : bool
    val deduplicate : bool
    val default_hack_builtin_models_rel : string
    val dependency_mode : bool
    val detach_analysis_dependency : bool
    val developer_mode : bool
    val dict_missing_key_var_block_list : Str.regexp option
    val differential_filter_files : string option
    val differential_filter_set : [ `Introduced | `Fixed | `Preexisting ] list
    val dotty_cfg_libs : bool
    val dump_duplicate_symbols : bool
    val dump_textual : bool
    val dynamic_dispatch_json_file_path : string option
    val erlang_ast_dir : string option
    val erlang_check_return : bool
    val erlang_list_unfold_depth : int
    val erlang_reliability : bool
    val erlang_skip_compile : bool
    val erlang_with_otp_specs : bool
    val extract_capture_from : string option
    val fail_on_bug : bool
    val fcp_apple_clang : string option
    val fcp_syntax_only : bool
    val file_renamings : string option
    val files_to_analyze_index : string option
    val filter_paths : bool
    val filtering : bool
    val force_delete_results_dir : bool
    val force_integration : build_system option
    val from_json_config_impact_report : string
    val from_json_costs_report : string
    val from_json_report : string
    val frontend_stats : bool
    val frontend_tests : bool
    val generated_classes : string option
    val genrule_mode : bool
    val global_tenv : bool
    val hackc_binary : string option
    type pulse_hack_builder_pattern = {
    1. class_name : string;
    2. finalizers : string list;
    3. immediately_non_discardable_class : string option;
    }
    type pulse_hack_builder_patterns = pulse_hack_builder_pattern list
    val hack_builder_patterns : pulse_hack_builder_patterns
    val hack_builtin_models : string
    val hack_models : string list
    val hack_naming_table : string option
    val hack_verify_capture_only : bool
    val help_checker : Checker.t list
    val help_issue_type : IssueType.t list
    val hoisting_report_only_expensive : bool
    val html : bool
    val icfg_dotty_outfile : string option
    val implicit_sdk_root : string option
    val impurity_report_immutable_modifications : bool
    val inclusive_cost : bool
    val incremental_analysis : bool
    val infer_binary : string

    absolute canonicalized path to the current executable

    val infer_is_clang : bool
    val infer_is_javac : bool
    val inferconfig_file : string option
    val inline_func_pointer_for_testing : string option
    val invalidate_only : bool
    val is_checker_enabled : Checker.t -> bool
    val issues_tests : string option
    val issues_tests_fields : IssuesTestField.t list
    val java_debug_source_file_info : string option
    val java_jar_compiler : string option
    val java_read_modules : bool
    val java_source_parser_experimental : bool
    val java_version : int option
    val javac_classes_out : string
    val job_id : string option
    val jobs : int
    val keep_going : bool
    val kotlin_capture : bool
    val lineage_source : string list
    val lineage_sink : string list
    val lineage_sanitizers : string list
    val lineage_limit : int option
    val lineage_dedup : bool
    val lineage_field_depth : int
    val lineage_field_max_cfg_size : int option
    val lineage_field_width : int
    val lineage_include_builtins : bool
    val lineage_json_report : bool
    val lineage_keep_temporaries : bool
    val lineage_max_cfg_size : int option
    val lineage_prevent_cycles : bool
    val lineage_seed : int
    val lineage_variant_width : int
    val list_categories : bool
    val list_checkers : bool
    val list_issue_types : bool
    val liveness_block_list_var_regex : Str.regexp option
    val liveness_dangerous_classes : Yojson.Safe.t
    val liveness_ignored_constant : string list
    val load_average : float option
    val lock_model : Yojson.Safe.t
    val log_pulse_disjunct_increase_after_model_call : bool
    val log_pulse_coverage : bool
    val log_missing_deps : bool
    val margin_html : int
    val mark_unchanged_procs : bool
    val mask_sajwa_exceptions : bool
    val max_nesting : int option
    val memtrace_analysis : bool
    val memtrace_sampling_rate : float
    val merge_capture : string list
    val merge_report : string list
    val merge_summaries : string list
    val modeled_expensive : string * Yojson.Safe.t
    val multicore : bool
    val never_returning_null : string * Yojson.Safe.t
    val noescaping_function_list : string list
    val no_censor_report : Str.regexp list
    val no_translate_libs : bool
    val nullable_annotation : string option
    val objc_block_execution_macro : string option
    val objc_synthesize_dealloc : bool
    val ondemand_recursion_restart_limit : int
    val only_cheap_debug : bool
    val oom_threshold : int option
    val pmd_xml : bool
    val preanalysis_html : bool
    val print_active_checkers : bool
    val print_builtins : bool
    val print_jbir : bool
    val print_logs : bool
    val print_types : bool
    val print_using_diff : bool
    val procedures : bool
    val procedures_attributes : bool
    val procedures_call_graph : bool
    val procedures_callees : bool
    val procedures_cfg : bool
    val procedures_definedness : bool
    val procedures_filter : string option
    val procedures_name : bool
    val procedures_source_file : bool
    val procedures_summary : bool
    val procedures_summary_json : bool
    val procedures_summary_skip_empty : bool
    val process_clang_ast : bool
    val procs_to_analyze_index : string option
    val progress_bar : [ `MultiLine | `Plain | `Quiet ]
    val project_root : string
    val pulse_balanced_disjuncts_strategy : bool
    val pulse_cut_to_one_path_procedures_pattern : Str.regexp option
    val pulse_force_continue : bool
    val pulse_havoc_arguments : bool
    val pulse_inline_global_init_func_pointer : bool
    val pulse_intraprocedural_only : bool
    val pulse_log_summary_count : bool
    val pulse_log_unknown_calls : bool
    val pulse_log_unknown_calls_sampled : int option
    val pulse_max_cfg_size : int
    val pulse_max_disjuncts : int
    val pulse_max_heap : int option
    val pulse_model_abort : string list
    val pulse_model_alloc_pattern : Str.regexp option
    val pulse_model_cheap_copy_type : Str.regexp option
    val pulse_model_free_pattern : Str.regexp option
    val pulse_model_malloc_pattern : Str.regexp option
    val pulse_model_realloc_pattern : Str.regexp option
    val pulse_model_release_pattern : Str.regexp option
    val pulse_model_return_first_arg : Str.regexp option
    val pulse_model_return_nonnull : Str.regexp option
    val pulse_model_return_this : Str.regexp option
    val pulse_model_returns_copy_pattern : Str.regexp option
    val pulse_model_skip_pattern : Str.regexp option
    val pulse_model_transfer_ownership : string list
    val pulse_model_transfer_ownership_namespace : (string * string) list
    val pulse_model_unknown_pure : Str.regexp option
    val pulse_model_unreachable : string list
    val pulse_models_for_erlang : string list
    val pulse_monitor_transitive_callees : bool
    val pulse_monitor_transitive_missed_captures : bool
    val pulse_nullsafe_report_npe : bool
    val pulse_nullsafe_report_npe_as_separate_issue_type : bool
    val pulse_over_approximate_reasoning : bool
    val pulse_prevent_non_disj_top : bool
    val pulse_recency_limit : int
    val pulse_report_flows_from_taint_source : string option
    val pulse_report_flows_to_taint_sink : string option
    val pulse_report_issues_for_tests : bool
    val pulse_report_latent_issues : bool
    val pulse_sanity_checks : bool
    val pulse_skip_procedures : Str.regexp option
    val pulse_specialization_iteration_limit : int
    val pulse_specialization_limit : int
    val pulse_specialization_partial : bool
    val pulse_taint_config : pulse_taint_config
    val pulse_taint_follow_field_accesses : bool
    val pulse_taint_opaque_files : string list
    val pulse_taint_short_traces : bool
    val pulse_taint_skip_sources : bool
    val pulse_transitive_access_config : string list
    val pulse_transitive_access_enabled : bool
    val pulse_transitive_access_verbose : bool
    val pulse_unsafe_malloc : bool
    val pulse_widen_threshold : int
    val pure_by_default : bool
    val pyc_file : string list
    val python_files_index : string option
    val python_skip_db : bool
    val qualified_cpp_name_block_list : string list
    val quiet : bool
    val racerd_always_report_java : bool
    val racerd_guardedby : bool
    val racerd_ignore_classes : IStdlib.IString.Set.t
    val reactive_mode : bool
    val reactive_capture : bool
    val reanalyze : bool
    val relative_path_backtrack : int
    val replay_analysis_schedule : bool
    val replay_ondemand_should_error : bool
    val report : bool
    val report_block_list_files_containing : string list
    val report_console_limit : int option
    val report_current : string option
    val report_custom_error : bool
    val report_force_relative_path : bool
    val report_formatter : [ `No_formatter | `Phabricator_formatter ]
    val report_path_regex_allow_list : string list
    val report_path_regex_block_list : string list
    val report_previous : string option
    val report_suppress_errors : string list
    val reports_include_ml_loc : bool
    val rest : string list
    val results_dir : string
    val run_as_child : int option
    val run_python_interpreter : bool
    val sarif : bool
    val scheduler : scheduler
    val scope_leakage_config : Yojson.Safe.t
    val select : [ `All | `Select of int ] option
    val show_buckets : bool
    val shrink_analysis_db : bool
    val siof_check_iostreams : bool
    val siof_safe_methods : string list
    val skip_analysis_in_path : Str.regexp option
    val skip_analysis_in_path_skips_compilation : bool
    val skip_duplicated_types : bool
    val skip_non_capture_clang_commands : bool
    val skip_translation_headers : string list
    val source_files : bool
    val source_files_call_graph : bool
    val source_files_call_graph_partition : int option
    val source_files_cfg : bool
    val source_files_filter : string option
    val source_files_freshly_captured : bool
    val source_files_procedure_names : bool
    val source_files_type_environment : bool
    val source_preview : bool
    val sourcepath : string option
    val sources : string list
    val sqlite_cache_size : int
    val sqlite_lock_timeout : int
    val sqlite_max_blob_size : int
    val sqlite_mmap_size : int
    val sqlite_page_size : int
    val sqlite_vfs : string option
    val starvation_c_function_pointer_models : Yojson.Safe.t
    val starvation_c_named_threads_annot : Yojson.Safe.t
    val starvation_skip_analysis : Yojson.Safe.t
    val starvation_strict_mode : bool
    val starvation_whole_program : bool
    val stats_dir_current : string option
    val stats_dir_previous : string option
    val struct_as_cpp_class : bool
    val store_analysis_schedule : bool
    val subtype_multirange : bool
    val suffix_match_changed_files : bool
    val summaries_caches_max_size : int
    val suppress_lint_ignore_types : bool
    val suppressions : bool
    val tenv_json : string option
    val testing_mode : bool
    val threadsafe_aliases : Yojson.Safe.t
    val timeout : float option
    val top_longest_proc_duration_size : int option
    val topl_max_conjuncts : int
    val topl_max_disjuncts : int
    val topl_properties : ToplAst.t list
    val topl_report_latent_issues : bool
    val trace_absarray : bool
    val trace_error : bool
    val trace_events : bool
    val trace_ondemand : bool
    val trace_topl : bool
    val unix_fork : bool
    val workspace : string option
    val write_html : bool
    val write_html_allow_list_regex : string list
    val write_website : string option
    val xcode_developer_dir : string option
    val xcode_isysroot_suffix : string option
    val xcpretty : bool

    Configuration values derived from command-line options

    val toplevel_results_dir : string

    In some integrations, eg Buck, infer subprocesses started by the build system (started by the toplevel infer process) will have their own results directory; this points to the results directory of the toplevel infer process, which can be useful for, eg, storing debug info. In other cases this is equal to results_dir.

    val java_package_is_external : string -> bool

    Check if a Java package is external to the repository

    val is_originator : bool

    is the current process (forked from) the root of the Infer process tree

    Global variables with initial values specified by command-line options

    val clang_compilation_dbs : [ `Escaped of string | `Raw of string ] list
    diff --git a/odoc/next/infer/IBase/EarlyScubaLogging/index.html b/odoc/next/infer/IBase/EarlyScubaLogging/index.html deleted file mode 100644 index 9e60cdbd851..00000000000 --- a/odoc/next/infer/IBase/EarlyScubaLogging/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -EarlyScubaLogging (infer.IBase.EarlyScubaLogging)

    Module IBase.EarlyScubaLogging

    val log_message : label:string -> message:string -> unit
    val finish : unit -> LogEntry.t list
    diff --git a/odoc/next/infer/IBase/ExecutionDuration/index.html b/odoc/next/infer/IBase/ExecutionDuration/index.html index fb2d93dc97d..d3283e86b70 100644 --- a/odoc/next/infer/IBase/ExecutionDuration/index.html +++ b/odoc/next/infer/IBase/ExecutionDuration/index.html @@ -1,2 +1,2 @@ -ExecutionDuration (infer.IBase.ExecutionDuration)

    Module IBase.ExecutionDuration

    type t
    val pp : prefix:string -> Stdlib.Format.formatter -> t -> unit
    type counter
    type 'a evaluation_result = {
    1. result : 'a;
    2. execution_duration : t;
    }
    val zero : t
    val counter : unit -> counter
    val since : counter -> t
    val add_duration_since : t -> counter -> t
    val add : t -> t -> t
    val wall_time : t -> Mtime.span
    val total_useful_s : t -> float

    seconds of user plus system time

    val timed_evaluate : f:(unit -> 'a) -> 'a evaluation_result
    val log : prefix:string -> Logging.debug_kind -> t -> unit

    log to debug logs and to Scuba

    val to_scuba_entries : prefix:string -> t -> LogEntry.t list
    +ExecutionDuration (infer.IBase.ExecutionDuration)

    Module IBase.ExecutionDuration

    type t
    val pp : prefix:string -> Stdlib.Format.formatter -> t -> unit
    type counter
    type 'a evaluation_result = {
    1. result : 'a;
    2. execution_duration : t;
    }
    val zero : t
    val counter : unit -> counter
    val since : counter -> t
    val add_duration_since : t -> counter -> t
    val add : t -> t -> t
    val wall_time : t -> Mtime.span
    val total_useful_s : t -> float

    seconds of user plus system time

    val timed_evaluate : f:(unit -> 'a) -> 'a evaluation_result
    val log : prefix:string -> Logging.debug_kind -> t -> unit

    log to debug logs and to stats

    val to_stats_entries : prefix:string -> t -> LogEntry.t list
    diff --git a/odoc/next/infer/IBase/IssueType/index.html b/odoc/next/infer/IBase/IssueType/index.html index 68177d383fa..ee0961d3175 100644 --- a/odoc/next/infer/IBase/IssueType/index.html +++ b/odoc/next/infer/IBase/IssueType/index.html @@ -6,4 +6,4 @@ ?user_documentation:string -> severity -> Checker.t -> - t

    Create a new issue and register it in the list of all issues. NOTE: if the issue with the same string id is already registered, overrides `hum` but DOES NOT override `enabled`. This trick allows to deal with disabling/enabling dynamic issues from the config, when we don't know all params yet. Thus, the human-readable description can be updated when we encounter the definition of the issue type.

    val checker_can_report : Checker.t -> t -> bool

    Whether the issue was registered as coming from the given checker. Important to call this before reporting to keep documentation accurate.

    val set_enabled : t -> bool -> unit
    val abduction_case_not_implemented : t
    val arbitrary_code_execution_under_lock : t
    val array_of_pointsto : t
    val array_out_of_bounds_l1 : t
    val array_out_of_bounds_l2 : t
    val array_out_of_bounds_l3 : t
    val assert_failure : t
    val bad_footprint : t
    val bad_arg : latent:bool -> t
    val bad_generator : latent:bool -> t
    val bad_key : latent:bool -> t
    val bad_map : latent:bool -> t
    val bad_record : latent:bool -> t
    val bad_return : latent:bool -> t
    val biabduction_analysis_stops : t
    val biabduction_retain_cycle : t
    val block_parameter_not_null_checked : t
    val buffer_overrun_l1 : t
    val buffer_overrun_l2 : t
    val buffer_overrun_l3 : t
    val buffer_overrun_l4 : t
    val buffer_overrun_l5 : t
    val buffer_overrun_s2 : t
    val buffer_overrun_u5 : t
    val cannot_star : t
    val captured_strong_self : t
    val checkers_allocates_memory : t

    Warning name when a performance critical method directly or indirectly calls a method allocating memory

    val checkers_annotation_reachability_error : t
    val checkers_calls_expensive_method : t

    Warning name when a performance critical method directly or indirectly calls a method annotatd as expensive

    val checkers_expensive_overrides_unexpensive : t

    Warning name for the subtyping rule: method not annotated as expensive cannot be overridden by a method annotated as expensive

    val checkers_fragment_retain_view : t
    val class_cast_exception : t
    val compared_to_null_and_dereferenced : t
    val complexity_increase : kind:CostKind.t -> is_on_ui_thread:bool -> t
    val condition_always_false : t
    val condition_always_true : t
    val config_impact_analysis : t
    val config_impact_analysis_strict : t
    val pulse_config_usage : t
    val pulse_const_refable : t
    val constant_address_dereference : latent:bool -> t
    val cxx_string_captured_in_block : t
    val cxx_ref_captured_in_block : t
    val dangling_pointer_dereference : t
    val dangling_pointer_dereference_maybe : t
    val data_flow_to_sink : t
    val dead_store : t
    val deadlock : t
    val static_constructor_stall : t
    val divide_by_zero : t
    val do_not_report : t

    an issue type that should never be reported

    val empty_vector_access : t
    val expensive_cost_call : kind:CostKind.t -> t
    val failure_exe : t
    val guardedby_violation : t
    val impure_function : t
    val inefficient_keyset_iterator : t
    val inferbo_alloc_is_big : t
    val inferbo_alloc_is_negative : t
    val inferbo_alloc_is_zero : t
    val inferbo_alloc_may_be_big : t
    val inferbo_alloc_may_be_negative : t
    val infinite_cost_call : kind:CostKind.t -> t
    val inherently_dangerous_function : t
    val integer_overflow_l1 : t
    val integer_overflow_l2 : t
    val integer_overflow_l5 : t
    val integer_overflow_u5 : t
    val interface_not_thread_safe : t
    val internal_error : t
    val invalid_sil : t
    val invariant_call : t
    val ipc_on_ui_thread : t
    val lab_resource_leak : t
    val leak_after_array_abstraction : t
    val leak_in_footprint : t
    val leak_unknown_origin : t
    val lockless_violation : t
    val lock_consistency_violation : t
    val expensive_loop_invariant_call : t
    val memory_leak : t
    val missing_fld : t
    val missing_required_prop : t
    val mixed_self_weakself : t
    val modifies_immutable : t
    val multiple_weakself : t
    val mutual_recursion_cycle : t
    val nil_block_call : latent:bool -> t
    val nil_insertion_into_collection : latent:bool -> t
    val nil_messaging_to_non_pod : latent:bool -> t
    val no_match_of_rhs : latent:bool -> t
    val no_matching_case_clause : latent:bool -> t
    val no_matching_else_clause : latent:bool -> t
    val no_matching_function_clause : latent:bool -> t
    val no_true_branch_in_if : latent:bool -> t
    val no_matching_branch_in_try : latent:bool -> t
    val ns_string_captured_in_block : t
    val null_argument : latent:bool -> t
    val null_dereference : t
    val nullptr_dereference : latent:bool -> t
    val nullptr_dereference_in_nullsafe_class : latent:bool -> t
    val optional_empty_access : latent:bool -> t
    val precondition_not_found : t
    val precondition_not_met : t
    val premature_nil_termination : t
    val pulse_cannot_instantiate_abstract_class : t
    val pulse_dict_missing_key : t
    val pulse_dynamic_type_mismatch : t
    val pulse_transitive_access : t
    val pulse_memory_leak_c : t
    val pulse_memory_leak_cpp : t
    val pulse_resource_leak : t
    val pulse_unawaited_awaitable : t
    val pulse_unfinished_builder : t
    val pulse_uninitialized_const : t
    val pulse_uninitialized_method : t
    val pure_function : t
    val readonly_shared_ptr_param : t
    val regex_op_on_ui_thread : t
    val resource_leak : t
    val retain_cycle : t
    val retain_cycle_no_weak_info : t
    val scope_leakage : t
    val self_in_block_passed_to_init : t
    val sensitive_data_flow : t
    val skip_function : t
    val stack_variable_address_escape : t
    val starvation : t
    val static_initialization_order_fiasco : t
    val strict_mode_violation : t
    val strong_self_not_checked : t
    val symexec_memory_error : t
    val taint_error : t
    val thread_safety_violation : t
    val topl_error : latent:bool -> t
    val uninitialized_value_pulse : t
    val unnecessary_copy_pulse : t
    val unnecessary_copy_assignment_pulse : t
    val unnecessary_copy_assignment_const_pulse : t
    val unnecessary_copy_assignment_movable_pulse : t
    val unnecessary_copy_intermediate_pulse : t
    val unnecessary_copy_intermediate_const_pulse : t
    val unnecessary_copy_movable_pulse : t
    val unnecessary_copy_optional_pulse : t
    val unnecessary_copy_optional_const_pulse : t
    val unnecessary_copy_return_pulse : t
    val unnecessary_copy_thrift_assignment_pulse : t
    val unreachable_code_after : t
    val use_after_delete : latent:bool -> t
    val use_after_free : latent:bool -> t
    val use_after_lifetime : latent:bool -> t
    val vector_invalidation : latent:bool -> t
    val pulse_reference_stability : t
    val weak_self_in_noescape_block : t
    val wrong_argument_number : t
    val unreachable_cost_call : kind:CostKind.t -> t
    val lineage_flow : t
    module Map : IStdlib.PrettyPrintable.PPMap with type key = t
    + t

    Create a new issue and register it in the list of all issues. NOTE: if the issue with the same string id is already registered, overrides `hum` but DOES NOT override `enabled`. This trick allows to deal with disabling/enabling dynamic issues from the config, when we don't know all params yet. Thus, the human-readable description can be updated when we encounter the definition of the issue type.

    val checker_can_report : Checker.t -> t -> bool

    Whether the issue was registered as coming from the given checker. Important to call this before reporting to keep documentation accurate.

    val set_enabled : t -> bool -> unit
    val abduction_case_not_implemented : t
    val arbitrary_code_execution_under_lock : t
    val array_of_pointsto : t
    val array_out_of_bounds_l1 : t
    val array_out_of_bounds_l2 : t
    val array_out_of_bounds_l3 : t
    val assert_failure : t
    val bad_footprint : t
    val bad_arg : latent:bool -> t
    val bad_generator : latent:bool -> t
    val bad_key : latent:bool -> t
    val bad_map : latent:bool -> t
    val bad_record : latent:bool -> t
    val bad_return : latent:bool -> t
    val biabduction_analysis_stops : t
    val biabduction_retain_cycle : t
    val block_parameter_not_null_checked : t
    val buffer_overrun_l1 : t
    val buffer_overrun_l2 : t
    val buffer_overrun_l3 : t
    val buffer_overrun_l4 : t
    val buffer_overrun_l5 : t
    val buffer_overrun_s2 : t
    val buffer_overrun_u5 : t
    val cannot_star : t
    val captured_strong_self : t
    val checkers_allocates_memory : t

    Warning name when a performance critical method directly or indirectly calls a method allocating memory

    val checkers_annotation_reachability_error : t
    val checkers_calls_expensive_method : t

    Warning name when a performance critical method directly or indirectly calls a method annotatd as expensive

    val checkers_expensive_overrides_unexpensive : t

    Warning name for the subtyping rule: method not annotated as expensive cannot be overridden by a method annotated as expensive

    val checkers_fragment_retain_view : t
    val class_cast_exception : t
    val compared_to_null_and_dereferenced : t
    val complexity_increase : kind:CostKind.t -> is_on_ui_thread:bool -> t
    val condition_always_false : t
    val condition_always_true : t
    val config_impact_analysis : t
    val config_impact_analysis_strict : t
    val pulse_config_usage : t
    val pulse_const_refable : t
    val constant_address_dereference : latent:bool -> t
    val cxx_string_captured_in_block : t
    val cxx_ref_captured_in_block : t
    val dangling_pointer_dereference : t
    val dangling_pointer_dereference_maybe : t
    val data_flow_to_sink : t
    val dead_store : t
    val deadlock : t
    val static_constructor_stall : t
    val divide_by_zero : t
    val do_not_report : t

    an issue type that should never be reported

    val empty_vector_access : t
    val expensive_cost_call : kind:CostKind.t -> t
    val failure_exe : t
    val guardedby_violation : t
    val impure_function : t
    val inefficient_keyset_iterator : t
    val inferbo_alloc_is_big : t
    val inferbo_alloc_is_negative : t
    val inferbo_alloc_is_zero : t
    val inferbo_alloc_may_be_big : t
    val inferbo_alloc_may_be_negative : t
    val infinite_cost_call : kind:CostKind.t -> t
    val infinite_recursion : t
    val inherently_dangerous_function : t
    val integer_overflow_l1 : t
    val integer_overflow_l2 : t
    val integer_overflow_l5 : t
    val integer_overflow_u5 : t
    val interface_not_thread_safe : t
    val internal_error : t
    val invalid_sil : t
    val invariant_call : t
    val ipc_on_ui_thread : t
    val lab_resource_leak : t
    val leak_after_array_abstraction : t
    val leak_in_footprint : t
    val leak_unknown_origin : t
    val lockless_violation : t
    val lock_consistency_violation : t
    val lock_on_ui_thread : t
    val expensive_loop_invariant_call : t
    val memory_leak : t
    val missing_fld : t
    val missing_required_prop : t
    val mixed_self_weakself : t
    val modifies_immutable : t
    val multiple_weakself : t
    val mutual_recursion_cycle : t
    val nil_block_call : latent:bool -> t
    val nil_insertion_into_collection : latent:bool -> t
    val nil_messaging_to_non_pod : latent:bool -> t
    val no_match_of_rhs : latent:bool -> t
    val no_matching_case_clause : latent:bool -> t
    val no_matching_else_clause : latent:bool -> t
    val no_matching_function_clause : latent:bool -> t
    val no_true_branch_in_if : latent:bool -> t
    val no_matching_branch_in_try : latent:bool -> t
    val ns_string_captured_in_block : t
    val null_argument : latent:bool -> t
    val null_dereference : t
    val nullptr_dereference : latent:bool -> t
    val nullptr_dereference_in_nullsafe_class : latent:bool -> t
    val optional_empty_access : latent:bool -> t
    val precondition_not_found : t
    val precondition_not_met : t
    val premature_nil_termination : t
    val pulse_cannot_instantiate_abstract_class : t
    val pulse_dict_missing_key : t
    val pulse_dynamic_type_mismatch : t
    val pulse_transitive_access : t
    val pulse_memory_leak_c : t
    val pulse_memory_leak_cpp : t
    val pulse_resource_leak : t
    val pulse_unawaited_awaitable : t
    val pulse_unfinished_builder : t
    val pulse_uninitialized_const : t
    val pulse_uninitialized_method : t
    val pure_function : t
    val readonly_shared_ptr_param : t
    val regex_op_on_ui_thread : t
    val resource_leak : t
    val retain_cycle : t
    val retain_cycle_no_weak_info : t
    val scope_leakage : t
    val self_in_block_passed_to_init : t
    val sensitive_data_flow : t
    val skip_function : t
    val stack_variable_address_escape : t
    val starvation : t
    val static_initialization_order_fiasco : t
    val strict_mode_violation : t
    val strong_self_not_checked : t
    val symexec_memory_error : t
    val taint_error : t
    val thread_safety_violation : t
    val topl_error : latent:bool -> t
    val uninitialized_value_pulse : t
    val unnecessary_copy_pulse : t
    val unnecessary_copy_assignment_pulse : t
    val unnecessary_copy_assignment_const_pulse : t
    val unnecessary_copy_assignment_movable_pulse : t
    val unnecessary_copy_intermediate_pulse : t
    val unnecessary_copy_intermediate_const_pulse : t
    val unnecessary_copy_movable_pulse : t
    val unnecessary_copy_optional_pulse : t
    val unnecessary_copy_optional_const_pulse : t
    val unnecessary_copy_return_pulse : t
    val unnecessary_copy_thrift_assignment_pulse : t
    val unreachable_code_after : t
    val use_after_delete : latent:bool -> t
    val use_after_free : latent:bool -> t
    val use_after_lifetime : latent:bool -> t
    val vector_invalidation : latent:bool -> t
    val pulse_reference_stability : t
    val weak_self_in_noescape_block : t
    val wrong_argument_number : t
    val unreachable_cost_call : kind:CostKind.t -> t
    val lineage_flow : t
    module Map : IStdlib.PrettyPrintable.PPMap with type key = t
    diff --git a/odoc/next/infer/IBase/Language/index.html b/odoc/next/infer/IBase/Language/index.html index fe445bdcb8a..f03b1a08fad 100644 --- a/odoc/next/infer/IBase/Language/index.html +++ b/odoc/next/infer/IBase/Language/index.html @@ -1,2 +1,2 @@ -Language (infer.IBase.Language)

    Module IBase.Language

    type t =
    1. | Clang
    2. | CIL
    3. | Erlang
    4. | Hack
    5. | Java
    6. | Python
    include Ppx_compare_lib.Comparable.S with type t := t
    val compare : t Base__Ppx_compare_lib.compare
    include Ppx_enumerate_lib.Enumerable.S with type t := t
    val all : t list
    val equal : t -> t -> bool
    val to_string : t -> string
    val curr_language : t IStdlib.IStd.ref
    val curr_language_is : t -> bool
    +Language (infer.IBase.Language)

    Module IBase.Language

    type t =
    1. | Clang
    2. | CIL
    3. | Erlang
    4. | Hack
    5. | Java
    6. | Python
    include Ppx_compare_lib.Comparable.S with type t := t
    val compare : t Base__Ppx_compare_lib.compare
    include Ppx_enumerate_lib.Enumerable.S with type t := t
    val all : t list
    val equal : t -> t -> bool
    val to_string : t -> string
    val curr_language_is : t -> bool
    val get_language : unit -> t
    val set_language : t -> unit
    diff --git a/odoc/next/infer/IBase/LogEntry/index.html b/odoc/next/infer/IBase/LogEntry/index.html index fd4cc4c950b..d4cdc1b3712 100644 --- a/odoc/next/infer/IBase/LogEntry/index.html +++ b/odoc/next/infer/IBase/LogEntry/index.html @@ -1,2 +1,2 @@ -LogEntry (infer.IBase.LogEntry)

    Module IBase.LogEntry

    Log entry data model, global log entry store and functions to manipulate it. Direct access to the store is not exposed.

    type count_entry_data = {
    1. value : int;
    }
    type time_entry_data = {
    1. duration_us : int;
    }
    type string_data = {
    1. message : string;
    }
    type entry_data =
    1. | Count of count_entry_data
    2. | Time of time_entry_data
    3. | String of string_data
    type t = {
    1. label : string;
    2. created_at_ts : int;
    3. data : entry_data;
    }

    created_at_ts is a unix timestamp (in seconds)

    val mk_count : label:string -> value:int -> t
    val mk_time : label:string -> duration_us:int -> t
    val mk_string : label:string -> message:string -> t
    val global_log_get : unit -> t list
    val global_log_erase : unit -> unit
    val global_log_add : t -> unit
    +LogEntry (infer.IBase.LogEntry)

    Module IBase.LogEntry

    Log entry data model, global log entry store and functions to manipulate it. Direct access to the store is not exposed.

    type count_entry_data = {
    1. value : int;
    }
    type time_entry_data = {
    1. duration_us : int;
    }
    type string_data = {
    1. message : string;
    }
    type entry_data =
    1. | Count of count_entry_data
    2. | Time of time_entry_data
    3. | String of string_data
    type t = {
    1. label : string;
    2. created_at_ts : int;
    3. data : entry_data;
    }

    created_at_ts is a unix timestamp (in seconds)

    val mk_count : label:string -> value:int -> t
    val mk_time : label:string -> duration_us:int -> t
    val mk_string : label:string -> message:string -> t
    val global_log_get : unit -> t list
    val global_log_erase : unit -> unit
    diff --git a/odoc/next/infer/IBase/Process/index.html b/odoc/next/infer/IBase/Process/index.html index 2379f95f47e..cb8c3c60d7a 100644 --- a/odoc/next/infer/IBase/Process/index.html +++ b/odoc/next/infer/IBase/Process/index.html @@ -1,7 +1,13 @@ -Process (infer.IBase.Process)

    Module IBase.Process

    val create_process_and_wait : prog:string -> args:string list -> unit

    Given an command to be executed, creates a process to execute this command, and waits for its execution. The standard out and error are not redirected. If the commands fails to execute, prints an error message and exits.

    type action =
    1. | ReadStdout
    2. | ReadStderr
    val create_process_and_wait_with_output : +Process (infer.IBase.Process)

    Module IBase.Process

    val create_process_and_wait : prog:string -> args:string list -> + ?env:Core_unix.env -> + unit -> + unit

    Given an command to be executed, creates a process to execute this command, and waits for its execution. If the commands fails to execute, prints an error message and exits.

    type action =
    1. | ReadStdout
    2. | ReadStderr
    val create_process_and_wait_with_output : + prog:string -> + args:string list -> + ?env:Core_unix.env -> action -> string

    Given an command to be executed, creates a process to execute this command, and waits for its execution. Depending on the action passed, either stdout or stderr is returned, with the other being streamed to the console. If the commands fails to execute, prints an error message and exits.

    val print_error_and_exit : ?exit_code:int -> diff --git a/odoc/next/infer/IBase/Scuba/index.html b/odoc/next/infer/IBase/Scuba/index.html deleted file mode 100644 index f402d15af65..00000000000 --- a/odoc/next/infer/IBase/Scuba/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Scuba (infer.IBase.Scuba)

    Module IBase.Scuba

    Low-level Scuba logging functionality. Provides functionality to log anything to any scuba table. (Note that Scuba is a schema-free storage, so it won't require any changes). Don't use this module directly for logging to tables with known structure. Use high-level functions that are aware of the table structure.

    type table =
    1. | InferEvents

    A scuba table

    type sample

    A sample to be added to Scuba

    val new_sample : time:int option -> sample

    Create an empty sample with given creation timestamp. If time is not specified, corresponds to current timestamp.

    val add_int : name:string -> value:int -> sample -> sample

    Set a new integer field and its value to the sample. Overwrites if a field with this name was already set.

    val add_normal : name:string -> value:string -> sample -> sample

    Set a new string (normal in Scuba terminology) field and its value to the sample. Overwrites if a field with this name was already set.

    val add_tagset : name:string -> value:string list -> sample -> sample

    Set a new set of strings (tagset in Scuba terminology) field and its value to the sample. Overwrites if a field with this name was already set.

    val log : table -> sample list -> unit

    The main function. Log a collection of samples to the given table.

    val sample_to_json : sample -> Yojson.t
    diff --git a/odoc/next/infer/IBase/SourceFile/index.html b/odoc/next/infer/IBase/SourceFile/index.html index e4a4d4d9862..00e6191fe67 100644 --- a/odoc/next/infer/IBase/SourceFile/index.html +++ b/odoc/next/infer/IBase/SourceFile/index.html @@ -1,2 +1,2 @@ -SourceFile (infer.IBase.SourceFile)

    Module IBase.SourceFile

    type t
    include Ppx_compare_lib.Comparable.S with type t := t
    val compare : t Base__Ppx_compare_lib.compare
    include Sexplib0.Sexpable.S with type t := t
    val t_of_sexp : Sexplib0__.Sexp.t -> t
    val sexp_of_t : t -> Sexplib0__.Sexp.t
    include Ppx_hash_lib.Hashable.S with type t := t
    val hash_fold_t : t Base__Ppx_hash_lib.hash_fold
    val hash : t -> Base__Ppx_hash_lib.Std.Hash.hash_value
    val hash_normalize : t -> t
    val hash_normalize_opt : t option -> t option
    val hash_normalize_list : t list -> t list
    module Map : Stdlib.Map.S with type key = t

    Maps from source_file

    module Set : Stdlib.Set.S with type elt = t

    Set of source files

    module Hash : Stdlib.Hashtbl.S with type key = t

    Mutable hash tables and sets keyed on source files

    module HashSet : IStdlib.HashSet.S with type elt = t
    val is_invalid : t -> bool

    Is the source file the invalid source file?

    val read_config_changed_files : unit -> Set.t option

    return the list of changed files as read from Config.changed_files_index. NOTE: it may include extra source_files if --changed-files-index contains paths to header files.

    val read_config_files_to_analyze : unit -> Set.t option

    return the list of files as read from Config.files_to_analyze_index. NOTE: it may include extra source_files if --changed-files-index contains paths to header files.

    val invalid : string -> t

    Invalid source file

    val equal : t -> t -> bool

    equality of source files

    val from_abs_path : ?warn_on_error:bool -> string -> t

    create source file from absolute path. WARNING: If warn_on_error is false, no warning will be shown whenever an error occurs for the given path (e.g. if it does not exist).

    val create : ?check_abs_path:bool -> ?check_rel_path:bool -> string -> t

    Create a SourceFile from a given path. If relative, it assumes it is w.r.t. project root. WARNING: if check_abs_path (check_rel_path) is true then a warning message is shown if the provided path is absolute (relative) and an error occurs when resolving (e.g. if it does not exist).

    val is_under_project_root : t -> bool

    Returns true if the file is under the project root or the workspace directory if it exists

    val of_header : ?warn_on_error:bool -> t -> t option

    Return approximate source file corresponding to the parameter if it's header file and file exists. returns None otherwise. WARNING: If warn_on_error is false, no warning will be shown whenever an error occurs for the given SourceFile (e.g. if it does not exist).

    val pp : Stdlib.Format.formatter -> t -> unit

    pretty print t

    val to_abs_path : t -> string

    get the full path of a source file

    val to_rel_path : t -> string

    get the relative path of a source file

    val to_string : ?force_relative:bool -> t -> string

    convert a source file to a string WARNING: result may not be valid file path, do not use this function to perform operations on filenames

    val has_extension : ext:string -> t -> bool

    returns whether the source file has provided extension

    val is_matching : IStdlib.IStd.Str.regexp list -> t -> bool

    Check if the source file path is matching with a regexp of the given regexp list.

    module SQLite : SqliteUtils.Data with type t = t
    +SourceFile (infer.IBase.SourceFile)

    Module IBase.SourceFile

    type t
    include Ppx_compare_lib.Comparable.S with type t := t
    val compare : t Base__Ppx_compare_lib.compare
    include Sexplib0.Sexpable.S with type t := t
    val t_of_sexp : Sexplib0__.Sexp.t -> t
    val sexp_of_t : t -> Sexplib0__.Sexp.t
    include Ppx_hash_lib.Hashable.S with type t := t
    val hash_fold_t : t Base__Ppx_hash_lib.hash_fold
    val hash : t -> Base__Ppx_hash_lib.Std.Hash.hash_value
    val hash_normalize : t -> t
    val hash_normalize_opt : t option -> t option
    val hash_normalize_list : t list -> t list
    module Map : Stdlib.Map.S with type key = t

    Maps from source_file

    module Set : Stdlib.Set.S with type elt = t

    Set of source files

    module Hash : Stdlib.Hashtbl.S with type key = t

    Mutable hash tables and sets keyed on source files

    module HashSet : IStdlib.HashSet.S with type elt = t
    val is_invalid : t -> bool

    Is the source file the invalid source file?

    val read_config_changed_files : unit -> Set.t option

    return the list of changed files as read from Config.changed_files_index. NOTE: it may include extra source_files if --changed-files-index contains paths to header files.

    val read_config_files_to_analyze : unit -> Set.t option

    return the list of files as read from Config.files_to_analyze_index. NOTE: it may include extra source_files if --changed-files-index contains paths to header files.

    val invalid : string -> t

    Invalid source file

    val equal : t -> t -> bool

    equality of source files

    val from_abs_path : ?warn_on_error:bool -> string -> t

    create source file from absolute path. WARNING: If warn_on_error is false, no warning will be shown whenever an error occurs for the given path (e.g. if it does not exist).

    val create : ?check_abs_path:bool -> ?check_rel_path:bool -> string -> t

    Create a SourceFile from a given path. If relative, it assumes it is w.r.t. project root. WARNING: if check_abs_path (check_rel_path) is true then a warning message is shown if the provided path is absolute (relative) and an error occurs when resolving (e.g. if it does not exist).

    val is_under_project_root : t -> bool

    Returns true if the file is under the project root or the workspace directory if it exists

    val of_header : ?warn_on_error:bool -> t -> t option

    Return approximate source file corresponding to the parameter if it's header file and file exists. returns None otherwise. WARNING: If warn_on_error is false, no warning will be shown whenever an error occurs for the given SourceFile (e.g. if it does not exist).

    val pp : Stdlib.Format.formatter -> t -> unit

    pretty print t

    val to_abs_path : t -> string

    get the full path of a source file

    val to_rel_path : t -> string

    get the relative path of a source file

    val to_string : ?force_relative:bool -> t -> string

    convert a source file to a string WARNING: result may not be valid file path, do not use this function to perform operations on filenames

    val has_extension : ext:string -> t -> bool

    returns whether the source file has provided extension

    val is_matching : Str.regexp list -> t -> bool

    Check if the source file path is matching with a regexp of the given regexp list.

    module SQLite : SqliteUtils.Data with type t = t
    diff --git a/odoc/next/infer/IBase/Stats/index.html b/odoc/next/infer/IBase/Stats/index.html index 28b90faf95a..b0949ccd39d 100644 --- a/odoc/next/infer/IBase/Stats/index.html +++ b/odoc/next/infer/IBase/Stats/index.html @@ -1,2 +1,2 @@ -Stats (infer.IBase.Stats)

    Module IBase.Stats

    collect statistics about backend/analysis operations

    type t
    val incr_summary_file_try_load : unit -> unit

    a query to the filesystem attempting to load a summary file

    val incr_summary_read_from_disk : unit -> unit

    a summary file is deserialized from disk

    val incr_summary_cache_hits : unit -> unit
    val incr_summary_cache_misses : unit -> unit
    val incr_summary_specializations : unit -> unit
    val incr_ondemand_procs_analyzed : unit -> unit
    val incr_ondemand_double_analysis_prevented : unit -> unit
    val incr_ondemand_recursion_cycle_restart_limit_hit : unit -> unit
    val add_to_proc_locker_lock_time : ExecutionDuration.t -> unit
    val add_to_proc_locker_unlock_time : ExecutionDuration.t -> unit
    val add_to_restart_scheduler_total_time : ExecutionDuration.t -> unit
    val add_to_restart_scheduler_useful_time : ExecutionDuration.t -> unit
    val incr_pulse_aliasing_contradictions : unit -> unit
    val incr_pulse_args_length_contradictions : unit -> unit
    val incr_pulse_captured_vars_length_contradictions : unit -> unit
    val add_pulse_disjuncts_dropped : int -> unit
    val add_pulse_interrupted_loops : int -> unit
    val incr_pulse_unknown_calls : unit -> unit
    val incr_pulse_unknown_calls_on_hack_resource : unit -> unit
    val incr_pulse_summaries_contradictions : unit -> unit
    val incr_pulse_summaries_unsat_for_caller : unit -> unit
    val incr_pulse_summaries_with_some_unreachable_nodes : unit -> unit
    val incr_pulse_summaries_with_some_unreachable_returns : unit -> unit
    val incr_pulse_summaries_count_0_continue_program : unit -> unit
    val add_pulse_summaries_count : int -> unit
    val add_proc_duration_us : string -> string -> int -> unit
    val incr_topl_reachable_calls : unit -> unit
    val incr_timeouts : unit -> unit
    val add_timing : Timeable.t -> float -> unit
    val set_process_times : ExecutionDuration.t -> unit
    val set_useful_times : ExecutionDuration.t -> unit
    val incr_spec_store_times : ExecutionDuration.counter -> unit
    val reset : unit -> unit

    reset all stats

    val get : unit -> t

    get the stats so far

    val log_aggregate : t list -> unit

    log aggregated stats to infer's log file and to Scuba

    +Stats (infer.IBase.Stats)

    Module IBase.Stats

    collect statistics about backend/analysis operations

    type t
    val incr_summary_file_try_load : unit -> unit

    a query to the filesystem attempting to load a summary file

    val incr_summary_read_from_disk : unit -> unit

    a summary file is deserialized from disk

    val incr_summary_cache_hits : unit -> unit
    val incr_summary_cache_misses : unit -> unit
    val incr_summary_specializations : unit -> unit
    val incr_ondemand_procs_analyzed : unit -> unit
    val incr_ondemand_double_analysis_prevented : unit -> unit
    val incr_ondemand_recursion_cycle_restart_limit_hit : unit -> unit
    val add_to_proc_locker_lock_time : ExecutionDuration.t -> unit
    val add_to_proc_locker_unlock_time : ExecutionDuration.t -> unit
    val add_to_restart_scheduler_total_time : ExecutionDuration.t -> unit
    val add_to_restart_scheduler_useful_time : ExecutionDuration.t -> unit
    val incr_pulse_aliasing_contradictions : unit -> unit
    val incr_pulse_args_length_contradictions : unit -> unit
    val incr_pulse_captured_vars_length_contradictions : unit -> unit
    val add_pulse_disjuncts_dropped : int -> unit
    val add_pulse_interrupted_loops : int -> unit
    val incr_pulse_unknown_calls : unit -> unit
    val incr_pulse_unknown_calls_on_hack_resource : unit -> unit
    val incr_pulse_summaries_contradictions : unit -> unit
    val incr_pulse_summaries_unsat_for_caller : unit -> unit
    val incr_pulse_summaries_with_some_unreachable_nodes : unit -> unit
    val incr_pulse_summaries_with_some_unreachable_returns : unit -> unit
    val incr_pulse_summaries_count_0_continue_program : unit -> unit
    val add_pulse_summaries_count : int -> unit
    val add_proc_duration_us : string -> string -> int -> unit
    val incr_topl_reachable_calls : unit -> unit
    val incr_timeouts : unit -> unit
    val add_timing : Timeable.t -> float -> unit
    val set_process_times : ExecutionDuration.t -> unit
    val set_useful_times : ExecutionDuration.t -> unit
    val incr_spec_store_times : ExecutionDuration.counter -> unit
    val reset : unit -> unit

    reset all stats

    val get : unit -> t

    get the stats so far

    val log_aggregate : t list -> unit

    log aggregated stats to infer's log file and to stats

    diff --git a/odoc/next/infer/IBase/ScubaLogging/index.html b/odoc/next/infer/IBase/StatsLogging/index.html similarity index 54% rename from odoc/next/infer/IBase/ScubaLogging/index.html rename to odoc/next/infer/IBase/StatsLogging/index.html index 1ede0645f93..5aba378d74d 100644 --- a/odoc/next/infer/IBase/ScubaLogging/index.html +++ b/odoc/next/infer/IBase/StatsLogging/index.html @@ -1,5 +1,5 @@ -ScubaLogging (infer.IBase.ScubaLogging)

    Module IBase.ScubaLogging

    Functionality for logging into "infer_events" Scuba table. The table is organized in form of key-value pairs. Two most important fields are "event" and "value". Other fields in the table correspond to things common for this particular run of Infer.

    val log_many : LogEntry.t list -> unit

    Log several events in one go. Useful when you do custom aggregations and have a place to log all aggregated results at once.

    val log_count : label:string -> value:int -> unit

    Log anything that can be counted. Events will be prefixed with "count."

    val log_duration : label:string -> duration_us:int -> unit

    Log elapsed time. Events will be prefixed with "time."

    val log_message : label:string -> message:string -> unit

    Log a string. Event is prefixed with "msg."

    val log_message_sampled : +StatsLogging (infer.IBase.StatsLogging)

    Module IBase.StatsLogging

    The two most important fields are "event" and "value". Other fields in the table correspond to things common for this particular run of Infer.

    val log_many : LogEntry.t list -> unit

    Log several events in one go. Useful when you do custom aggregations and have a place to log all aggregated results at once.

    val log_count : label:string -> value:int -> unit

    Log anything that can be counted. Events will be prefixed with "count."

    val log_duration : label:string -> duration_us:int -> unit

    Log elapsed time. Events will be prefixed with "time."

    val log_message : label:string -> message:string -> unit

    Log a string. Event is prefixed with "msg."

    val log_message_sampled : label:string IStdlib.IStd.Lazy.t -> message:string IStdlib.IStd.Lazy.t -> sample_rate:int -> @@ -13,4 +13,4 @@ message:string IStdlib.IStd.Lazy.t -> sample_rate:int -> unit
    val execute_with_time_logging : string -> (unit -> 'a) -> 'a

    A helper to log execution time of a particular function. Use this to measure a performance of a given function. Example:

    let f a b = <some code>
    -let f a b = ScubaLogging.execute_with_time_logging "f" (fun () -> f a b)
    val register_global_log_flushing_at_exit : unit -> unit
    +let f a b = StatsLogging.execute_with_time_logging "f" (fun () -> f a b)
    val register_global_log_flushing_at_exit : unit -> unit
    diff --git a/odoc/next/infer/IBase/StatsSample/index.html b/odoc/next/infer/IBase/StatsSample/index.html new file mode 100644 index 00000000000..1d6a1727c91 --- /dev/null +++ b/odoc/next/infer/IBase/StatsSample/index.html @@ -0,0 +1,2 @@ + +StatsSample (infer.IBase.StatsSample)

    Module IBase.StatsSample

    type sample

    A stats sample

    val new_sample : time:int option -> sample

    Create an empty sample with given creation timestamp. If time is not specified, corresponds to current timestamp.

    val add_int : name:string -> value:int -> sample -> sample

    Set a new integer field and its value to the sample. Overwrites if a field with this name was already set.

    val add_normal : name:string -> value:string -> sample -> sample

    Set a new string field and its value to the sample. Overwrites if a field with this name was already set.

    val sample_to_json : sample -> Yojson.t
    diff --git a/odoc/next/infer/IBase/Timings/index.html b/odoc/next/infer/IBase/Timings/index.html index c1522a41dc9..3ecab78878b 100644 --- a/odoc/next/infer/IBase/Timings/index.html +++ b/odoc/next/infer/IBase/Timings/index.html @@ -1,2 +1,2 @@ -Timings (infer.IBase.Timings)

    Module IBase.Timings

    module F = Stdlib.Format

    Data structure to collect timing percentile informations on all Timeable.t elements

    type t
    val init : t
    val add : Timeable.t -> float -> t -> t

    register a new timing measurement

    val merge : t -> t -> t
    val pp : F.formatter -> t -> unit
    type serialized
    val serialize : t -> serialized
    val deserialize : serialized -> t
    val to_scuba : t -> LogEntry.t list
    +Timings (infer.IBase.Timings)

    Module IBase.Timings

    module F = Stdlib.Format

    Data structure to collect timing percentile informations on all Timeable.t elements

    type t
    val init : t
    val add : Timeable.t -> float -> t -> t

    register a new timing measurement

    val merge : t -> t -> t
    val pp : F.formatter -> t -> unit
    type serialized
    val serialize : t -> serialized
    val deserialize : serialized -> t
    val to_stats : t -> LogEntry.t list
    diff --git a/odoc/next/infer/IBase/ToplAst/index.html b/odoc/next/infer/IBase/ToplAst/index.html index d921ae1cb6f..b1152e69887 100644 --- a/odoc/next/infer/IBase/ToplAst/index.html +++ b/odoc/next/infer/IBase/ToplAst/index.html @@ -11,7 +11,7 @@ unit
    val show_register_name : register_name -> string
    type variable_name = string
    val pp_variable_name : Ppx_show_runtime.Format.formatter -> variable_name -> - unit
    val show_variable_name : variable_name -> string
    type field_name = string
    val pp_field_name : Ppx_show_runtime.Format.formatter -> field_name -> unit
    val show_field_name : field_name -> string
    type class_name = string
    val pp_class_name : Ppx_show_runtime.Format.formatter -> class_name -> unit
    val show_class_name : class_name -> string
    type constant =
    1. | LiteralInt of int
    2. | LiteralStr of string
    val pp_constant : Ppx_show_runtime.Format.formatter -> constant -> unit
    val show_constant : constant -> string
    type value =
    1. | Constant of constant
    2. | Register of register_name
    3. | Binding of variable_name
    4. | FieldAccess of {
      1. value : value;
      2. class_name : class_name;
      3. field_name : field_name;
      }
    val pp_value : Ppx_show_runtime.Format.formatter -> value -> unit
    val show_value : value -> string
    type binop =
    1. | LeadsTo
    2. | OpEq
    3. | OpNe
    4. | OpGe
    5. | OpGt
    6. | OpLe
    7. | OpLt
    val pp_binop : Ppx_show_runtime.Format.formatter -> binop -> unit
    val show_binop : binop -> string
    type predicate =
    1. | Binop of binop * value * value
    2. | Value of value
    val pp_predicate : Ppx_show_runtime.Format.formatter -> predicate -> unit
    val show_predicate : predicate -> string
    type condition = predicate list
    val pp_condition : Ppx_show_runtime.Format.formatter -> condition -> unit
    val show_condition : condition -> string
    type assignment = register_name * variable_name
    val pp_assignment : Ppx_show_runtime.Format.formatter -> assignment -> unit
    val show_assignment : assignment -> string
    type regex = {
    1. re_text : string;
    2. re : IStdlib.IStd.Str.regexp;
    }
    val pp_regex : Ppx_show_runtime.Format.formatter -> regex -> unit
    val show_regex : regex -> string
    val mk_regex : string -> regex
    type call_pattern = {
    1. procedure_name_regex : regex;
    2. type_regexes : regex option list option;
    }
    val pp_call_pattern : Ppx_show_runtime.Format.formatter -> call_pattern -> unit
    val show_call_pattern : call_pattern -> string
    type label_pattern =
    1. | ArrayWritePattern
    2. | CallPattern of call_pattern
    val pp_label_pattern : + unit
    val show_variable_name : variable_name -> string
    type field_name = string
    val pp_field_name : Ppx_show_runtime.Format.formatter -> field_name -> unit
    val show_field_name : field_name -> string
    type class_name = string
    val pp_class_name : Ppx_show_runtime.Format.formatter -> class_name -> unit
    val show_class_name : class_name -> string
    type constant =
    1. | LiteralInt of int
    2. | LiteralStr of string
    val pp_constant : Ppx_show_runtime.Format.formatter -> constant -> unit
    val show_constant : constant -> string
    type value =
    1. | Constant of constant
    2. | Register of register_name
    3. | Binding of variable_name
    4. | FieldAccess of {
      1. value : value;
      2. class_name : class_name;
      3. field_name : field_name;
      }
    val pp_value : Ppx_show_runtime.Format.formatter -> value -> unit
    val show_value : value -> string
    type binop =
    1. | LeadsTo
    2. | OpEq
    3. | OpNe
    4. | OpGe
    5. | OpGt
    6. | OpLe
    7. | OpLt
    val pp_binop : Ppx_show_runtime.Format.formatter -> binop -> unit
    val show_binop : binop -> string
    type predicate =
    1. | Binop of binop * value * value
    2. | Value of value
    val pp_predicate : Ppx_show_runtime.Format.formatter -> predicate -> unit
    val show_predicate : predicate -> string
    type condition = predicate list
    val pp_condition : Ppx_show_runtime.Format.formatter -> condition -> unit
    val show_condition : condition -> string
    type assignment = register_name * variable_name
    val pp_assignment : Ppx_show_runtime.Format.formatter -> assignment -> unit
    val show_assignment : assignment -> string
    type regex = {
    1. re_text : string;
    2. re : Str.regexp;
    }
    val pp_regex : Ppx_show_runtime.Format.formatter -> regex -> unit
    val show_regex : regex -> string
    val mk_regex : string -> regex
    type call_pattern = {
    1. procedure_name_regex : regex;
    2. type_regexes : regex option list option;
    }
    val pp_call_pattern : Ppx_show_runtime.Format.formatter -> call_pattern -> unit
    val show_call_pattern : call_pattern -> string
    type label_pattern =
    1. | ArrayWritePattern
    2. | CallPattern of call_pattern
    val pp_label_pattern : Ppx_show_runtime.Format.formatter -> label_pattern -> unit
    val show_label_pattern : label_pattern -> string
    type label = {
    1. arguments : variable_name list option;
    2. condition : condition;
    3. action : assignment list;
    4. pattern : label_pattern;
    }
    val pp_label : Ppx_show_runtime.Format.formatter -> label -> unit
    val show_label : label -> string
    type vertex = string
    val compare_vertex : vertex -> vertex -> int
    val hash_fold_vertex : diff --git a/odoc/next/infer/IBase/ToplLexer/index.html b/odoc/next/infer/IBase/ToplLexer/index.html index 129a5e252b6..39618c646ff 100644 --- a/odoc/next/infer/IBase/ToplLexer/index.html +++ b/odoc/next/infer/IBase/ToplLexer/index.html @@ -1,2 +1,2 @@ -ToplLexer (infer.IBase.ToplLexer)

    Module IBase.ToplLexer

    exception ToplLexerBug
    val new_line : string -> string -> Stdlib.Lexing.lexbuf -> ToplParser.token
    val quoted : IStdlib.IStd.Str.regexp
    val unquote : string -> string
    val __ocaml_lex_tables : Stdlib.Lexing.lex_tables
    val raw_token : Stdlib.Lexing.lexbuf -> ToplParser.token
    val __ocaml_lex_raw_token_rec : Stdlib.Lexing.lexbuf -> int -> ToplParser.token
    val token : unit -> Stdlib.Lexing.lexbuf -> ToplParser.token
    +ToplLexer (infer.IBase.ToplLexer)

    Module IBase.ToplLexer

    exception ToplLexerBug
    val new_line : string -> string -> Stdlib.Lexing.lexbuf -> ToplParser.token
    val quoted : Str.regexp
    val unquote : string -> string
    val __ocaml_lex_tables : Stdlib.Lexing.lex_tables
    val raw_token : Stdlib.Lexing.lexbuf -> ToplParser.token
    val __ocaml_lex_raw_token_rec : Stdlib.Lexing.lexbuf -> int -> ToplParser.token
    val token : unit -> Stdlib.Lexing.lexbuf -> ToplParser.token
    diff --git a/odoc/next/infer/IBase/Utils/index.html b/odoc/next/infer/IBase/Utils/index.html index ef2467e781a..abe8c512175 100644 --- a/odoc/next/infer/IBase/Utils/index.html +++ b/odoc/next/infer/IBase/Utils/index.html @@ -22,7 +22,7 @@ (IStdlib.IStd.In_channel.t -> 'a) -> 'a * IStdlib.IStd.Unix.Exit_or_signal.t
    val create_dir : string -> unit

    recursively create a directory if it does not exist already

    val out_channel_create_with_dir : IStdlib.IStd.Filename.t -> - IStdlib.IStd.Out_channel.t

    create an out channel with creating missing directories

    val realpath : ?warn_on_error:bool -> string -> string

    realpath warn_on_error path returns path with all symbolic links resolved. It caches results of previous calls to avoid expensive system calls. WARNING: If warn_on_error is false, no warning will be shown whenever an error occurs for the given path (e.g. if it does not exist).

    val suppress_stderr2 : ('a -> 'b -> 'c) -> 'a -> 'b -> 'c

    wraps a function expecting 2 arguments in another that temporarily redirects stderr to /dev/null for the duration of the function call

    val rmtree : ?except:string list -> string -> unit

    rmtree path removes path and, if path is a directory, recursively removes its contents. Files whose name matches the absolute paths in except are not removed. If except is specified then path will only be spared if path appears literally in except (whereas files that are deeper will match if their absolute path is in except).

    val rm_all_in_dir : ?except:string list -> string -> unit

    rm_all_in_dir ?except path removes all entries in path/* except for the (absolute) paths in except

    val iter_dir : string -> f:(string -> unit) -> unit

    iterate on each entry in the directory except for "." and ".."

    val better_hash : 'a -> Stdlib.Digest.t

    Hashtbl.hash only hashes the first 10 meaningful values, better_hash uses everything.

    delete temporary file on exit

    val strip_balanced_once : drop:(char -> bool) -> string -> string

    drop at most one layer of well-balanced first and last characters satisfying drop from the string; for instance, strip_balanced ~drop:(function | 'a' | 'x' -> true | _ -> false) "xaabax" returns "aaba"

    val timeit : f:(unit -> 'a) -> 'a * Mtime.Span.t

    Returns the execution time of f together with its result

    val do_in_dir : dir:string -> f:(unit -> 'a) -> 'a

    executes f after cding into dir and then restores original cwd

    val get_available_memory_MB : unit -> int option

    On Linux systems, return Some x where MemAvailable x is in /proc/meminfo. Returns None in all other cases.

    val fold_infer_deps : + IStdlib.IStd.Out_channel.t

    create an out channel with creating missing directories

    val realpath : ?warn_on_error:bool -> string -> string

    realpath warn_on_error path returns path with all symbolic links resolved. It caches results of previous calls to avoid expensive system calls. WARNING: If warn_on_error is false, no warning will be shown whenever an error occurs for the given path (e.g. if it does not exist).

    val suppress_stderr2 : ('a -> 'b -> 'c) -> 'a -> 'b -> 'c

    wraps a function expecting 2 arguments in another that temporarily redirects stderr to /dev/null for the duration of the function call

    val rmtree : ?except:string list -> string -> unit

    rmtree path removes path and, if path is a directory, recursively removes its contents. Files whose name matches the absolute paths in except are not removed. If except is specified then path will only be spared if path appears literally in except (whereas files that are deeper will match if their absolute path is in except).

    val rm_all_in_dir : ?except:string list -> string -> unit

    rm_all_in_dir ?except path removes all entries in path/* except for the (absolute) paths in except

    val iter_dir : string -> f:(string -> unit) -> unit

    iterate on each entry in the directory except for "." and ".."

    val better_hash : 'a -> Stdlib.Digest.t

    Hashtbl.hash only hashes the first 10 meaningful values, better_hash uses everything.

    delete temporary file on exit

    val strip_balanced_once : drop:(char -> bool) -> string -> string

    drop at most one layer of well-balanced first and last characters satisfying drop from the string; for instance, strip_balanced ~drop:(function | 'a' | 'x' -> true | _ -> false) "xaabax" returns "aaba"

    val timeit : f:(unit -> 'a) -> 'a * Mtime.Span.t

    Returns the execution time of f together with its result

    val do_in_dir : dir:string -> f:(unit -> 'a) -> 'a

    executes f after cding into dir and then restores original cwd. Uses a mutex to prevent races on chdir in multicore mode.

    val get_available_memory_MB : unit -> int option

    On Linux systems, return Some x where MemAvailable x is in /proc/meminfo. Returns None in all other cases.

    val fold_infer_deps : root:string -> string -> init:'a -> @@ -31,4 +31,4 @@ init:'a -> f:('a -> Zip.in_file -> Zip.entry -> 'a) -> zip_filename:string -> - 'a

    fold over each file in the given zip_filename.

    val is_term_dumb : unit -> bool

    Check if the terminal is "dumb" or otherwise has very limited functionality. For example, Emacs' eshell reports itself as a dumb terminal.

    + 'a

    fold over each file in the given zip_filename.

    val is_term_dumb : unit -> bool

    Check if the terminal is "dumb" or otherwise has very limited functionality. For example, Emacs' eshell reports itself as a dumb terminal.

    val with_dls : 'a IStdlib.IStd.DLS.key -> f:('a -> 'a) -> unit

    get value in domain local storage, pass to f and set to result

    diff --git a/odoc/next/infer/IBase/index.html b/odoc/next/infer/IBase/index.html index 264763ec22b..d7c9f66c975 100644 --- a/odoc/next/infer/IBase/index.html +++ b/odoc/next/infer/IBase/index.html @@ -1,2 +1,2 @@ -IBase (infer.IBase)

    Module IBase

    module AnalysisRequest : sig ... end
    module BuckMode : sig ... end
    module Checker : sig ... end
    module CommandDoc : sig ... end
    module CommandLineOption : sig ... end

    Definition and parsing of command line arguments

    module Config : sig ... end

    Configuration values: either constant, determined at compile time, or set at startup time by system calls, environment variables, or command line options

    module CostIssues : sig ... end
    module CostIssuesTestField : sig ... end
    module CostKind : sig ... end
    module DB : sig ... end

    Database of analysis results

    module DBWriter : sig ... end
    module Database : sig ... end
    module Die : sig ... end
    module EarlyScubaLogging : sig ... end
    module Epilogues : sig ... end
    module Exception : sig ... end

    The restart scheduler and biabduction use exceptions for control flow (restarts/timeouts respectively). Functions here abstract away the semantics of when an exception can be ignored.

    module ExecutionDuration : sig ... end
    module FileDiff : sig ... end
    module ForkUtils : sig ... end
    module IssueType : sig ... end
    module IssuesTestField : sig ... end
    module Language : sig ... end
    module LineReader : sig ... end

    Module to read specific lines from files. The data from any file will stay in memory until the handle is collected by the gc

    module Location : sig ... end
    module LogEntry : sig ... end

    Log entry data model, global log entry store and functions to manipulate it. Direct access to the store is not exposed.

    module Logging : sig ... end

    log messages at different levels of verbosity

    module MarkupFormatter : sig ... end
    module MissingDependencyException : sig ... end
    module PayloadId : sig ... end
    module PerfEvent : sig ... end
    module Process : sig ... end
    module ProcessPool : sig ... end
    module ProcessPoolState : sig ... end
    module RestartSchedulerException : sig ... end
    module ResultsDir : sig ... end
    module ResultsDirEntryName : sig ... end

    Entries in the results directory (infer-out/).

    module Scuba : sig ... end

    Low-level Scuba logging functionality. Provides functionality to log anything to any scuba table. (Note that Scuba is a schema-free storage, so it won't require any changes). Don't use this module directly for logging to tables with known structure. Use high-level functions that are aware of the table structure.

    module ScubaLogging : sig ... end

    Functionality for logging into "infer_events" Scuba table. The table is organized in form of key-value pairs. Two most important fields are "event" and "value". Other fields in the table correspond to things common for this particular run of Infer.

    module Serialization : sig ... end

    Serialization of data stuctures

    module SourceFile : sig ... end
    module SqliteUtils : sig ... end
    module Stats : sig ... end

    collect statistics about backend/analysis operations

    module TaskBar : sig ... end
    module Timeable : sig ... end
    module Timer : sig ... end

    Time long-running operations listed in Timeable under a timeout

    module Timings : sig ... end
    module ToplAst : sig ... end
    module ToplLexer : sig ... end
    module ToplParser : sig ... end
    module Utils : sig ... end
    module Version : sig ... end
    +IBase (infer.IBase)

    Module IBase

    module AnalysisRequest : sig ... end
    module BuckMode : sig ... end
    module Checker : sig ... end
    module CommandDoc : sig ... end
    module CommandLineOption : sig ... end

    Definition and parsing of command line arguments

    module Config : sig ... end

    Configuration values: either constant, determined at compile time, or set at startup time by system calls, environment variables, or command line options

    module CostIssues : sig ... end
    module CostIssuesTestField : sig ... end
    module CostKind : sig ... end
    module DB : sig ... end

    Database of analysis results

    module DBWriter : sig ... end
    module Database : sig ... end
    module Die : sig ... end
    module Epilogues : sig ... end
    module Exception : sig ... end

    The restart scheduler and biabduction use exceptions for control flow (restarts/timeouts respectively). Functions here abstract away the semantics of when an exception can be ignored.

    module ExecutionDuration : sig ... end
    module FileDiff : sig ... end
    module ForkUtils : sig ... end
    module IssueType : sig ... end
    module IssuesTestField : sig ... end
    module Language : sig ... end
    module LineReader : sig ... end

    Module to read specific lines from files. The data from any file will stay in memory until the handle is collected by the gc

    module Location : sig ... end
    module LogEntry : sig ... end

    Log entry data model, global log entry store and functions to manipulate it. Direct access to the store is not exposed.

    module Logging : sig ... end

    log messages at different levels of verbosity

    module MarkupFormatter : sig ... end
    module MissingDependencyException : sig ... end
    module PayloadId : sig ... end
    module PerfEvent : sig ... end
    module Process : sig ... end
    module ProcessPool : sig ... end
    module ProcessPoolState : sig ... end
    module RestartSchedulerException : sig ... end
    module ResultsDir : sig ... end
    module ResultsDirEntryName : sig ... end

    Entries in the results directory (infer-out/).

    module Serialization : sig ... end

    Serialization of data stuctures

    module SourceFile : sig ... end
    module SqliteUtils : sig ... end
    module Stats : sig ... end

    collect statistics about backend/analysis operations

    module StatsLogging : sig ... end

    The two most important fields are "event" and "value". Other fields in the table correspond to things common for this particular run of Infer.

    module StatsSample : sig ... end
    module TaskBar : sig ... end
    module Timeable : sig ... end
    module Timer : sig ... end

    Time long-running operations listed in Timeable under a timeout

    module Timings : sig ... end
    module ToplAst : sig ... end
    module ToplLexer : sig ... end
    module ToplParser : sig ... end
    module Utils : sig ... end
    module Version : sig ... end
    diff --git a/odoc/next/infer/IR/AnalysisGlobalState/index.html b/odoc/next/infer/IR/AnalysisGlobalState/index.html index bc5f3b5170d..d2f3709ff4c 100644 --- a/odoc/next/infer/IR/AnalysisGlobalState/index.html +++ b/odoc/next/infer/IR/AnalysisGlobalState/index.html @@ -1,9 +1,12 @@ -AnalysisGlobalState (infer.IR.AnalysisGlobalState)

    Module IR.AnalysisGlobalState

    Global state for the backend analyses

    While global state should be kept under control at possible (so try to introduce as little of it as possible!), it is sometimes too convenient to ignore. This module lets us do it safely, at least until infer becomes multicore. In particular, global state is appropriately and safely stashed away and restored when the analysis of a procedure is suspended to go analyze another procedure with ondemand (see the Backend.Ondemand module).

    type t
    val save : unit -> t
    val restore : t -> unit
    val initialize : Procdesc.t -> Tenv.t -> unit
    val register : +AnalysisGlobalState (infer.IR.AnalysisGlobalState)

    Module IR.AnalysisGlobalState

    Global state for the backend analyses

    While global state should be kept under control at possible (so try to introduce as little of it as possible!), it is sometimes too convenient to ignore. This module lets us do it safely. In particular, global state (really, domain-local state) is appropriately and safely stashed away and restored when the analysis of a procedure is suspended to go analyze another procedure with ondemand (see the Backend.Ondemand module).

    type t
    val save : unit -> t
    val restore : t -> unit
    val initialize : Procdesc.t -> Tenv.t -> unit
    val register : init:(unit -> unit) -> save:(unit -> 'a) -> restore:('a -> unit) -> - unit

    Register pieces of global state from other analysis modules:

    • save and restore are called when suspending/resuming the analysis of the procedure when we need to go analyze a dependency
    • init is called when the analysis of a procedure starts
    val register_ref : init:(unit -> 'a) -> 'a IStdlib.IStd.ref -> unit

    special case of a value stored in a reference; init sets the ref to init ()

    val register_ref_with_proc_desc_and_tenv : + unit

    Register pieces of global state from other analysis modules:

    • save and restore are called when suspending/resuming the analysis of the procedure when we need to go analyze a dependency
    • init is called when the analysis of a procedure starts
    val register_ref : init:(unit -> 'a) -> 'a IStdlib.IStd.ref -> unit

    special case of a value stored in a reference; init sets the ref to init ()

    val register_dls : init:(unit -> 'a) -> 'a IStdlib.IStd.DLS.key -> unit

    special case of a value stored in domain-local storage; init sets the ref to init ()

    val register_dls_with_proc_desc_and_tenv : + init:(Procdesc.t -> Tenv.t -> 'a) -> + 'a IStdlib.IStd.DLS.key -> + unit

    special case of a value stored in domain local storage

    val register_ref_with_proc_desc_and_tenv : init:(Procdesc.t -> Tenv.t -> 'a) -> 'a IStdlib.IStd.ref -> unit

    same as register_ref but init takes a proc desc and a tenv

    diff --git a/odoc/next/infer/IR/CallFlags/index.html b/odoc/next/infer/IR/CallFlags/index.html index e99b2ba1a06..57c5157e95e 100644 --- a/odoc/next/infer/IR/CallFlags/index.html +++ b/odoc/next/infer/IR/CallFlags/index.html @@ -1,2 +1,2 @@ -CallFlags (infer.IR.CallFlags)

    Module IR.CallFlags

    The Smallfoot Intermediate Language: Call Flags

    module F = Stdlib.Format
    type t = {
    1. cf_assign_last_arg : bool;
    2. cf_injected_destructor : bool;
      (*

      true if this is an implicit C++ destructor call injected by the clang frontend

      *)
    3. cf_interface : bool;
    4. cf_is_objc_block : bool;
    5. cf_virtual : bool;
    }

    Flags for a procedure call

    include Ppx_compare_lib.Comparable.S with type t := t
    val compare : t Base__Ppx_compare_lib.compare
    include Ppx_compare_lib.Equal.S with type t := t
    val equal : t Base__Ppx_compare_lib.equal
    include Ppx_hash_lib.Hashable.S with type t := t
    val hash_fold_t : t Base__Ppx_hash_lib.hash_fold
    val hash : t -> Base__Ppx_hash_lib.Std.Hash.hash_value
    val hash_normalize : t -> t
    val hash_normalize_opt : t option -> t option
    val hash_normalize_list : t list -> t list
    val pp : F.formatter -> t -> unit
    val default : t

    Default value where all fields are set to false

    +CallFlags (infer.IR.CallFlags)

    Module IR.CallFlags

    The Smallfoot Intermediate Language: Call Flags

    module F = Stdlib.Format
    type t = {
    1. cf_assign_last_arg : bool;
    2. cf_injected_destructor : bool;
      (*

      true if this is an implicit C++ destructor call injected by the clang frontend

      *)
    3. cf_interface : bool;
    4. cf_is_objc_block : bool;
    5. cf_is_objc_getter_setter : bool;
    6. cf_virtual : bool;
    }

    Flags for a procedure call

    include Ppx_compare_lib.Comparable.S with type t := t
    val compare : t Base__Ppx_compare_lib.compare
    include Ppx_compare_lib.Equal.S with type t := t
    val equal : t Base__Ppx_compare_lib.equal
    include Ppx_hash_lib.Hashable.S with type t := t
    val hash_fold_t : t Base__Ppx_hash_lib.hash_fold
    val hash : t -> Base__Ppx_hash_lib.Std.Hash.hash_value
    val hash_normalize : t -> t
    val hash_normalize_opt : t option -> t option
    val hash_normalize_list : t list -> t list
    val pp : F.formatter -> t -> unit
    val default : t

    Default value where all fields are set to false

    diff --git a/odoc/next/infer/IR/Dependencies/index.html b/odoc/next/infer/IR/Dependencies/index.html index b2491f921dd..6529b302de1 100644 --- a/odoc/next/infer/IR/Dependencies/index.html +++ b/odoc/next/infer/IR/Dependencies/index.html @@ -1,2 +1,2 @@ -Dependencies (infer.IR.Dependencies)

    Module IR.Dependencies

    module F = Stdlib.Format
    type complete = {
    1. summary_loads : Procname.t list;
    2. recursion_edges : Procname.Set.t;
    3. other_proc_names : Procname.t list;
    4. used_tenv_sources : IBase.SourceFile.t list;
    }
    type t =
    1. | Partial
    2. | Complete of complete
      (*

      Dependencies are partial and mutable while the summary to which they belong is being computed, then made complete and immutable once the summary is fully analyzed.

      *)
    val pp : F.formatter -> t -> unit

    Mutable state keeping track during on-demand interprocedural analysis of (1) which procedure is currently being analyzed and (2) which procedures type environments were used to compute summaries.

    Located here in the IR module to avoid adding parameters threading the currently-under-analysis procedure throughout various analysis engine and checker code. These dependencies are then used in the Backend module to conservatively invalidate procedure summaries that were computed using out-of-date type environment information.

    val currently_under_analysis : Procname.t option IStdlib.IStd.ref
    val reset : Procname.t -> t
    val freeze : Procname.t -> t -> complete
    val complete_exn : t -> complete
    type kind =
    1. | SummaryLoad
      (*

      the summary of a procedure was queried

      *)
    2. | RecursionEdge
      (*

      ondemand returned an empty summary because a mutual recursion cycle was detected

      *)
    3. | Other
      (*

      anything else, eg the attributes of the function were loaded

      *)
    val record_pname_dep : ?caller:Procname.t -> kind -> Procname.t -> unit
    val record_srcfile_dep : IBase.SourceFile.t -> unit
    val clear : unit -> unit

    drop all currently-recorded dependency edges to reclaim memory

    val merge : complete -> complete -> complete
    +Dependencies (infer.IR.Dependencies)

    Module IR.Dependencies

    module F = Stdlib.Format
    type complete = {
    1. summary_loads : Procname.t list;
    2. recursion_edges : Procname.Set.t;
    3. other_proc_names : Procname.t list;
    4. used_tenv_sources : IBase.SourceFile.t list;
    }
    type t =
    1. | Partial
    2. | Complete of complete
      (*

      Dependencies are partial and mutable while the summary to which they belong is being computed, then made complete and immutable once the summary is fully analyzed.

      *)
    val pp : F.formatter -> t -> unit

    Mutable state keeping track during on-demand interprocedural analysis of (1) which procedure is currently being analyzed and (2) which procedures type environments were used to compute summaries.

    Located here in the IR module to avoid adding parameters threading the currently-under-analysis procedure throughout various analysis engine and checker code. These dependencies are then used in the Backend module to conservatively invalidate procedure summaries that were computed using out-of-date type environment information.

    val currently_under_analysis : Procname.t option IStdlib.IStd.DLS.key
    val reset : Procname.t -> t
    val freeze : Procname.t -> t -> complete
    val complete_exn : t -> complete
    type kind =
    1. | SummaryLoad
      (*

      the summary of a procedure was queried

      *)
    2. | RecursionEdge
      (*

      ondemand returned an empty summary because a mutual recursion cycle was detected

      *)
    3. | Other
      (*

      anything else, eg the attributes of the function were loaded

      *)
    val record_pname_dep : ?caller:Procname.t -> kind -> Procname.t -> unit
    val record_srcfile_dep : IBase.SourceFile.t -> unit
    val clear : unit -> unit

    drop all currently-recorded dependency edges to reclaim memory

    val merge : complete -> complete -> complete
    diff --git a/odoc/next/infer/IR/Fieldname/index.html b/odoc/next/infer/IR/Fieldname/index.html index f395d8fd0f0..9e1d1cd2216 100644 --- a/odoc/next/infer/IR/Fieldname/index.html +++ b/odoc/next/infer/IR/Fieldname/index.html @@ -17,4 +17,4 @@ Mangled.t -> captured_data -> is_weak:bool -> - t
    val is_capture_field_in_closure : t -> bool
    val is_weak : t -> bool option
    val is_capture_field_in_closure_by_ref : t -> bool
    val is_capture_field_function_pointer : t -> bool
    val is_java : t -> bool
    val is_java_synthetic : t -> bool

    Check if the field is autogenerated/synthetic *

    val is_internal : t -> bool

    Check if the field has the prefix "__" or "_M_" (internal field of std::thread::id)

    module Set : IStdlib.PrettyPrintable.PPSet with type elt = t

    Set for fieldnames

    module Map : IStdlib.PrettyPrintable.PPMap with type key = t

    Map for fieldnames

    val is_java_outer_instance : t -> bool

    Check if the field is the synthetic this$n of a nested class, used to access the n-th outer instance.

    val to_string : t -> string

    Convert a field name to a string.

    val to_full_string : t -> string
    val to_simplified_string : t -> string

    Convert a fieldname to a simplified string with at most one-level path. For example,

    • In C++: "<ClassName>::<FieldName>"
    • In Java, ObjC, C#: "<ClassName>.<FieldName>"
    • In C: "<StructName>.<FieldName>" or "<UnionName>.<FieldName>"
    • In Erlang: "<FieldName>"
    val patterns_match : IStdlib.IStd.Str.regexp list -> t -> bool

    Test whether a field full string matches to one of the regular expressions.

    val pp : F.formatter -> t -> unit

    Pretty print a field name.

    + t
    val is_capture_field_in_closure : t -> bool
    val is_weak : t -> bool option
    val is_capture_field_in_closure_by_ref : t -> bool
    val is_capture_field_function_pointer : t -> bool
    val is_java : t -> bool
    val is_java_synthetic : t -> bool

    Check if the field is autogenerated/synthetic *

    val is_internal : t -> bool

    Check if the field has the prefix "__" or "_M_" (internal field of std::thread::id)

    module Set : IStdlib.PrettyPrintable.PPSet with type elt = t

    Set for fieldnames

    module Map : IStdlib.PrettyPrintable.PPMap with type key = t

    Map for fieldnames

    val is_java_outer_instance : t -> bool

    Check if the field is the synthetic this$n of a nested class, used to access the n-th outer instance.

    val to_string : t -> string

    Convert a field name to a string.

    val to_full_string : t -> string
    val to_simplified_string : t -> string

    Convert a fieldname to a simplified string with at most one-level path. For example,

    • In C++: "<ClassName>::<FieldName>"
    • In Java, ObjC, C#: "<ClassName>.<FieldName>"
    • In C: "<StructName>.<FieldName>" or "<UnionName>.<FieldName>"
    • In Erlang: "<FieldName>"
    val patterns_match : Str.regexp list -> t -> bool

    Test whether a field full string matches to one of the regular expressions.

    val pp : F.formatter -> t -> unit

    Pretty print a field name.

    diff --git a/odoc/next/infer/IR/Io_infer/Html/index.html b/odoc/next/infer/IR/Io_infer/Html/index.html index 946ce8e2b65..da88bf99684 100644 --- a/odoc/next/infer/IR/Io_infer/Html/index.html +++ b/odoc/next/infer/IR/Io_infer/Html/index.html @@ -1,14 +1,9 @@ -Html (infer.IR.Io_infer.Html)

    Module Io_infer.Html

    val close : (IStdlib.IStd.Unix.File_descr.t * Stdlib.Format.formatter) -> unit

    Close an Html file

    val create : +Html (infer.IR.Io_infer.Html)

    Module Io_infer.Html

    type t = + IStdlib.IStd.Unix.File_descr.t * Stdlib.Format.formatter IStdlib.IStd.DLS.key
    val close : t -> unit

    Close an Html file

    Create a new html file

    val modified_during_analysis : IBase.SourceFile.t -> IBase.DB.Results_dir.path -> - IStdlib.IStd.Unix.File_descr.t * Stdlib.Format.formatter

    Create a new html file

    val modified_during_analysis : - IBase.SourceFile.t -> - IBase.DB.Results_dir.path -> - bool

    Return true if the html file was modified since the beginning of the analysis

    val node_filename : Procname.t -> int -> string

    File name for the node, given the procedure name and node id

    val open_out : - IBase.SourceFile.t -> - IBase.DB.Results_dir.path -> - IStdlib.IStd.Unix.File_descr.t * Stdlib.Format.formatter

    Open an Html file to append data

    Return true if the html file was modified since the beginning of the analysis

    val node_filename : Procname.t -> int -> string

    File name for the node, given the procedure name and node id

    Open an Html file to append data

    + t

    Create a Python procedure name.

    val empty_block : t

    Empty block name.

    val get_language : t -> IBase.Language.t

    Return the language of the procedure.

    val get_method : t -> string

    Return the method/function of a procname.

    val is_objc_block : t -> bool

    Return whether the procname is a block procname.

    val is_cpp_lambda : t -> bool

    Return whether the procname is a cpp lambda procname.

    val is_cpp_method : t -> bool

    Return whether the procname is a cpp method.

    val is_objc_dealloc : t -> bool

    Return whether the dealloc method of an Objective-C class.

    val is_objc_init : t -> bool

    Return whether the init method of an Objective-C class.

    val is_c_method : t -> bool

    Return true this is an Objective-C/C++ method name.

    val is_clang : t -> bool

    Return true this is an Objective-C/C++ method name or a C function.

    val is_constructor : t -> bool

    Check if this is a constructor.

    val is_csharp : t -> bool

    Check if this is a CSharp procedure name.

    val is_hack : t -> bool

    Check if this is a Hack procedure name.

    val is_java : t -> bool

    Check if this is a Java procedure name.

    val is_python : t -> bool

    Check if this is a Python procedure name.

    val objc_cpp_replace_method_name : t -> string -> t
    val is_infer_undefined : t -> bool

    Check if this is a special Infer undefined procedure.

    val is_static : t -> bool option

    Check if a procedure is a static class method or not. If the procedure is not a class method or is unknown to be static, it returns None. For now, this checking does not work on C++ methods.

    val get_global_name_of_initializer : t -> string option

    Return the name of the global for which this procedure is the initializer if this is an initializer, None otherwise.

    val pp_without_templates : Stdlib.Format.formatter -> t -> unit

    Pretty print a c++ proc name for the user to see.

    val pp : Stdlib.Format.formatter -> t -> unit

    Pretty print a proc name for the user to see.

    val pp_verbose : Stdlib.Format.formatter -> t -> unit

    Pretty print a proc name for the user to see with verbosity parameter.

    val to_string : ?verbosity:detail_level -> t -> string

    Convert a proc name into a string for the user to see.

    val to_string_verbose : t -> string

    Convert a proc name into a string for the user to see with verbosity parameter.

    val describe : Stdlib.Format.formatter -> t -> unit

    to use in user messages

    val replace_class : t -> ?arity_incr:int -> Typ.Name.t -> t

    Replace the class name component of a procedure name. In case of Java, replace package and class name.

    val is_method_in_objc_protocol : t -> bool
    val pp_simplified_string : ?withclass:bool -> F.formatter -> t -> unit

    Pretty print a proc name as an easy string for the user to see in an IDE.

    val to_simplified_string : ?withclass:bool -> t -> string

    Convert a proc name into an easy string for the user to see in an IDE.

    val from_string_c_fun : string -> t

    Convert a string to a c function name.

    val replace_java_inner_class_prefix_regex : string -> string

    Replace "$[0-9]+" index into "$_" in Java proc name.

    val hashable_name : t -> string

    Convert the procedure name in a format suitable for computing the bug hash.

    val pp_unique_id : F.formatter -> t -> unit

    Print a proc name as a unique identifier.

    val to_unique_id : t -> string

    Convert a proc name into a unique identifier.

    val to_short_unique_name : t -> string

    Convert a proc name into a unique identfier guaranteed to be short (less than 50 characters)

    val to_filename : t -> string

    Convert a proc name to a filename.

    val get_qualifiers : t -> QualifiedCppName.t

    get qualifiers of C/objc/C++ method/function

    val decr_hack_arity : t -> t option

    return a Hack procname with decremented arity. Return None if input has no arity or 0 arity

    val get_hack_arity : t -> int option

    get the arity of a Hack procname

    val get_hack_static_constinit : is_trait:bool -> HackClassName.t -> t

    get the constinit procname in Hack

    val pp_name_only : F.formatter -> t -> unit

    Print name of procedure with at most one-level path. For example,

    • In C++: "<ClassName>::<ProcName>"
    • In Java, ObjC, C#: "<ClassName>.<ProcName>"
    • In C: "<ProcName>"
    • In Erlang: "<ModuleName>:<ProcName>"
    val pp_fullname_only : F.formatter -> t -> unit

    Like pp_name_only, but include package name for Java.

    val is_c : t -> bool
    val is_lambda_name : string -> bool
    val is_lambda : t -> bool
    val is_lambda_or_block : t -> bool
    val patterns_match : Str.regexp list -> t -> bool

    Test whether a proc name matches to one of the regular expressions.

    val is_erlang_unsupported : t -> bool
    val is_erlang : t -> bool
    val erlang_call_unqualified : arity:int -> t

    A special infer-erlang procname that represents a syntactic erlang (unqualified) function call. arity is the arity of the erlang function. First parameter of this procedure is expecteed to be the erlang function name, and the remaining parameters are the erlang parameters (given one-by-one and not as an erlang list).

    val erlang_call_qualified : arity:int -> t

    Same as erlang_call_unqualified but is expected to have an erlang module name as the first parameter, and the function name as second. arity is (still) the erlang arity of the function.

    val is_erlang_call_unqualified : t -> bool
    val is_erlang_call_qualified : t -> bool
    val has_hack_classname : t -> bool
    val is_hack_async_name : t -> bool
    val is_hack_builtins : t -> bool
    val is_hack_constinit : t -> bool
    val is_hack_construct : t -> bool
    val is_hack_internal : t -> bool
    val is_hack_invoke : t -> bool
    val is_hack_late_binding : t -> bool
    val is_hack_xinit : t -> bool
    diff --git a/odoc/next/infer/IR/PythonClassName/index.html b/odoc/next/infer/IR/PythonClassName/index.html index 20c50ad0a3e..97ed42d18ca 100644 --- a/odoc/next/infer/IR/PythonClassName/index.html +++ b/odoc/next/infer/IR/PythonClassName/index.html @@ -1,2 +1,2 @@ -PythonClassName (infer.IR.PythonClassName)

    Module IR.PythonClassName

    module F = Stdlib.Format
    type t
    include Ppx_compare_lib.Comparable.S with type t := t
    val compare : t Base__Ppx_compare_lib.compare
    include Ppx_compare_lib.Equal.S with type t := t
    val equal : t Base__Ppx_compare_lib.equal
    val yojson_of_t : t -> Ppx_yojson_conv_lib.Yojson.Safe.t
    include Sexplib0.Sexpable.S with type t := t
    val t_of_sexp : Sexplib0__.Sexp.t -> t
    val sexp_of_t : t -> Sexplib0__.Sexp.t
    include Ppx_hash_lib.Hashable.S with type t := t
    val hash_fold_t : t Base__Ppx_hash_lib.hash_fold
    val hash : t -> Base__Ppx_hash_lib.Std.Hash.hash_value
    val hash_normalize : t -> t
    val hash_normalize_opt : t option -> t option
    val hash_normalize_list : t list -> t list
    val make : string -> t
    val classname : t -> string
    val components : t -> string list
    val wildcard : t
    val pp : F.formatter -> t -> unit
    val to_string : t -> string
    val static_companion : t -> t

    return the class of the companion class object of this class eg: Foo -> Foo$static

    val static_companion_origin : t -> t

    return the origin class of a companion class object eg: Foo$static -> Foo. the result is not specified if is the name is not a valid static class name

    val is_static : t -> bool

    tests if the name is a valid static class name (ie. ends with "$static")

    +PythonClassName (infer.IR.PythonClassName)

    Module IR.PythonClassName

    module F = Stdlib.Format
    type t
    include Ppx_compare_lib.Comparable.S with type t := t
    val compare : t Base__Ppx_compare_lib.compare
    include Ppx_compare_lib.Equal.S with type t := t
    val equal : t Base__Ppx_compare_lib.equal
    val yojson_of_t : t -> Ppx_yojson_conv_lib.Yojson.Safe.t
    include Sexplib0.Sexpable.S with type t := t
    val t_of_sexp : Sexplib0__.Sexp.t -> t
    val sexp_of_t : t -> Sexplib0__.Sexp.t
    include Ppx_hash_lib.Hashable.S with type t := t
    val hash_fold_t : t Base__Ppx_hash_lib.hash_fold
    val hash : t -> Base__Ppx_hash_lib.Std.Hash.hash_value
    val hash_normalize : t -> t
    val hash_normalize_opt : t option -> t option
    val hash_normalize_list : t list -> t list
    val make : string -> t
    val classname : t -> string
    val components : t -> string list
    val wildcard : t
    val pp : F.formatter -> t -> unit
    val to_string : t -> string
    val is_final : t -> bool
    val is_module : t -> bool
    val is_module_attribute : t -> bool
    val get_module_attribute_infos : t -> (t * string) option

    will return the pair (module_name, attribute) params of the type iff the type name is a module attribute type

    val get_module_name : t -> string option

    will return the string representation of the module iff type name is a module type

    val globals_prefix : string
    diff --git a/odoc/next/infer/IR/Typ/Name/index.html b/odoc/next/infer/IR/Typ/Name/index.html index e32ab8a1cd3..2b7d3a90483 100644 --- a/odoc/next/infer/IR/Typ/Name/index.html +++ b/odoc/next/infer/IR/Typ/Name/index.html @@ -1,2 +1,2 @@ -Name (infer.IR.Typ.Name)

    Module Typ.Name

    type t = name

    Named types.

    include Ppx_compare_lib.Comparable.S with type t := t
    val compare : t Base__Ppx_compare_lib.compare
    val yojson_of_t : t -> Ppx_yojson_conv_lib.Yojson.Safe.t
    include Sexplib0.Sexpable.S with type t := t
    val t_of_sexp : Sexplib0__.Sexp.t -> t
    val sexp_of_t : t -> Sexplib0__.Sexp.t
    include Ppx_hash_lib.Hashable.S with type t := t
    val hash_fold_t : t Base__Ppx_hash_lib.hash_fold
    val hash_normalize : t -> t
    val hash_normalize_opt : t option -> t option
    val hash_normalize_list : t list -> t list
    val compare_name : t -> t -> int

    Similar to compare, but compares only names, except template arguments.

    val equal : t -> t -> bool

    Equality for typenames

    val hash : t -> int
    val to_string : t -> string

    convert the typename to a string

    val pp : Stdlib.Format.formatter -> t -> unit
    val is_class : t -> bool

    is_class name holds if name names CPP/Objc/Java class

    val is_union : t -> bool

    is_union name holds if name names C/CPP union

    val is_same_type : t -> t -> bool

    is_class name1 name2 holds if name1 and name2 name same kind of type

    val name_without_templates : t -> string

    name of the c++ typename without qualifier

    val name : t -> string

    name of the typename

    val qual_name : t -> QualifiedCppName.t

    qualified name of the type, may return nonsense for Java classes

    val unqualified_name : t -> QualifiedCppName.t
    val get_template_spec_info : t -> template_spec_info option
    val is_objc_protocol : t -> bool
    val is_objc_class : t -> bool
    val is_objc_block : t -> bool
    val is_hack_class : t -> bool
    val is_python_class : t -> bool
    module C : sig ... end
    module CSharp : sig ... end
    module Hack : sig ... end
    module Java : sig ... end
    module Cpp : sig ... end
    module Objc : sig ... end
    module Set : IStdlib.PrettyPrintable.PPSet with type elt = t
    module Map : IStdlib.PrettyPrintable.PPMap with type key = t
    module Hash : Stdlib.Hashtbl.S with type key = t
    +Name (infer.IR.Typ.Name)

    Module Typ.Name

    type t = name

    Named types.

    include Ppx_compare_lib.Comparable.S with type t := t
    val compare : t Base__Ppx_compare_lib.compare
    val yojson_of_t : t -> Ppx_yojson_conv_lib.Yojson.Safe.t
    include Sexplib0.Sexpable.S with type t := t
    val t_of_sexp : Sexplib0__.Sexp.t -> t
    val sexp_of_t : t -> Sexplib0__.Sexp.t
    include Ppx_hash_lib.Hashable.S with type t := t
    val hash_fold_t : t Base__Ppx_hash_lib.hash_fold
    val hash_normalize : t -> t
    val hash_normalize_opt : t option -> t option
    val hash_normalize_list : t list -> t list
    val compare_name : t -> t -> int

    Similar to compare, but compares only names, except template arguments.

    val equal : t -> t -> bool

    Equality for typenames

    val hash : t -> int
    val to_string : t -> string

    convert the typename to a string

    val pp : Stdlib.Format.formatter -> t -> unit
    val is_class : t -> bool

    is_class name holds if name names CPP/Objc/Java class

    val is_union : t -> bool

    is_union name holds if name names C/CPP union

    val is_same_type : t -> t -> bool

    is_class name1 name2 holds if name1 and name2 name same kind of type

    val name_without_templates : t -> string

    name of the c++ typename without qualifier

    val name : t -> string

    name of the typename

    val qual_name : t -> QualifiedCppName.t

    qualified name of the type, may return nonsense for Java classes

    val unqualified_name : t -> QualifiedCppName.t
    val get_template_spec_info : t -> template_spec_info option
    val is_objc_protocol : t -> bool
    val is_objc_class : t -> bool
    val is_objc_block : t -> bool
    val is_hack_class : t -> bool
    val is_python_class : t -> bool
    val is_python_final : t -> bool
    val is_python_module : t -> bool
    val is_python_module_attribute : t -> bool
    val get_python_module_name : t -> string option
    val get_python_module_attribute_infos : t -> (t * string) option
    module C : sig ... end
    module CSharp : sig ... end
    module Hack : sig ... end
    module Java : sig ... end
    module Cpp : sig ... end
    module Objc : sig ... end
    module Set : IStdlib.PrettyPrintable.PPSet with type elt = t
    module Map : IStdlib.PrettyPrintable.PPMap with type key = t
    module Hash : Stdlib.Hashtbl.S with type key = t
    diff --git a/odoc/next/infer/IStdlib/IStd/index.html b/odoc/next/infer/IStdlib/IStd/index.html index f5853e9c317..760468cc22e 100644 --- a/odoc/next/infer/IStdlib/IStd/index.html +++ b/odoc/next/infer/IStdlib/IStd/index.html @@ -390,4 +390,4 @@ Ppx_hash_lib.Std.Hash.state
    val hash_unit : Core__.Import.unit -> Ppx_hash_lib.Std.Hash.hash_value
    val sexp_of_unit : Core__.Import.unit -> Sexplib0.Sexp.t
    val unit_of_sexp : Sexplib0.Sexp.t -> Core__.Import.unit
    val unit_sexp_grammar : Core__.Import.unit Sexplib0.Sexp_grammar.t
    val typerep_of_unit : Core__.Import.unit Typerep_lib.Std.Typerep.t
    val typename_of_unit : Core__.Import.unit Typerep_lib.Std.Typename.t
    val sexp_of_exn : Core__.Import.Exn.t -> Sexplib0.Sexp.t
    exception Not_found
    • deprecated [since 2018-02] Instead of raising [Not_found], consider using [raise_s] with an informative error message. If code needs to distinguish [Not_found] from other exceptions, please change it to handle both [Not_found] and [Not_found_s]. Then, instead -of raising [Not_found], raise [Not_found_s] with an informative error message.
    exception Not_found_s of Sexplib0.Sexp.t
    val phys_equal : 'a -> 'a -> Core__.Import.bool
    type !'a _maybe_bound = 'a Maybe_bound.t =
    1. | Incl of 'a
    2. | Excl of 'a
    3. | Unbounded
    val am_running_test : bool
    val does_raise : (unit -> 'a) -> bool
    val sec : Core__.Import.float -> Time_float.Span.t
    val (^/) : Base.string -> Base.string -> Base.string
    module Core_private = Core.Core_private
    module Core_kernel_private = Core_private
    module Unix = Core_unix
    module Str = Re.Str
    module Filename : sig ... end
    module Sys : sig ... end
    val compare : No_polymorphic_compare.compare
    val equal : No_polymorphic_compare.compare
    val (=) : No_polymorphic_compare.compare
    val failwith : 'a -> [ `use_Logging_die_instead ]
    val failwithf : 'a -> [ `use_Logging_die_instead ]
    val invalid_arg : 'a -> [ `use_Logging_die_instead ]
    val invalid_argf : 'a -> [ `use_Logging_die_instead ]
    val exit : [> `In_general_prefer_using_Logging_exit_over_Pervasives_exit ]
    module ANSITerminal : module type of ANSITerminal
    +of raising [Not_found], raise [Not_found_s] with an informative error message.
    exception Not_found_s of Sexplib0.Sexp.t
    val phys_equal : 'a -> 'a -> Core__.Import.bool
    type !'a _maybe_bound = 'a Maybe_bound.t =
    1. | Incl of 'a
    2. | Excl of 'a
    3. | Unbounded
    val am_running_test : bool
    val does_raise : (unit -> 'a) -> bool
    val sec : Core__.Import.float -> Time_float.Span.t
    val (^/) : Base.string -> Base.string -> Base.string
    module Core_private = Core.Core_private
    module Core_kernel_private = Core_private
    module Unix = Core_unix
    module Filename : sig ... end
    module Sys : sig ... end
    module DLS = Stdlib.Domain.DLS
    val compare : No_polymorphic_compare.compare
    val equal : No_polymorphic_compare.compare
    val (=) : No_polymorphic_compare.compare
    val failwith : 'a -> [ `use_Logging_die_instead ]
    val failwithf : 'a -> [ `use_Logging_die_instead ]
    val invalid_arg : 'a -> [ `use_Logging_die_instead ]
    val invalid_argf : 'a -> [ `use_Logging_die_instead ]
    val exit : [> `In_general_prefer_using_Logging_exit_over_Pervasives_exit ]
    module ANSITerminal : module type of ANSITerminal
    diff --git a/odoc/next/infer/IStdlib/IString/Map/index.html b/odoc/next/infer/IStdlib/IString/Map/index.html new file mode 100644 index 00000000000..d75f2c952a4 --- /dev/null +++ b/odoc/next/infer/IStdlib/IString/Map/index.html @@ -0,0 +1,14 @@ + +Map (infer.IStdlib.IString.Map)

    Module IString.Map

    include PrettyPrintable.PPMap with type key = string
    include Stdlib.Map.S with type key = string
    type key = string
    type !+'a t
    val empty : 'a t
    val add : key -> 'a -> 'a t -> 'a t
    val add_to_list : key -> 'a -> 'a list t -> 'a list t
    val update : key -> ('a option -> 'a option) -> 'a t -> 'a t
    val singleton : key -> 'a -> 'a t
    val remove : key -> 'a t -> 'a t
    val merge : + (key -> 'a option -> 'b option -> 'c option) -> + 'a t -> + 'b t -> + 'c t
    val union : (key -> 'a -> 'a -> 'a option) -> 'a t -> 'a t -> 'a t
    val cardinal : 'a t -> int
    val bindings : 'a t -> (key * 'a) list
    val min_binding : 'a t -> key * 'a
    val min_binding_opt : 'a t -> (key * 'a) option
    val max_binding : 'a t -> key * 'a
    val max_binding_opt : 'a t -> (key * 'a) option
    val choose : 'a t -> key * 'a
    val choose_opt : 'a t -> (key * 'a) option
    val find : key -> 'a t -> 'a
    val find_opt : key -> 'a t -> 'a option
    val find_first : (key -> bool) -> 'a t -> key * 'a
    val find_first_opt : (key -> bool) -> 'a t -> (key * 'a) option
    val find_last : (key -> bool) -> 'a t -> key * 'a
    val find_last_opt : (key -> bool) -> 'a t -> (key * 'a) option
    val iter : (key -> 'a -> unit) -> 'a t -> unit
    val fold : (key -> 'a -> 'acc -> 'acc) -> 'a t -> 'acc -> 'acc
    val map : ('a -> 'b) -> 'a t -> 'b t
    val mapi : (key -> 'a -> 'b) -> 'a t -> 'b t
    val filter : (key -> 'a -> bool) -> 'a t -> 'a t
    val filter_map : (key -> 'a -> 'b option) -> 'a t -> 'b t
    val partition : (key -> 'a -> bool) -> 'a t -> 'a t * 'a t
    val split : key -> 'a t -> 'a t * 'a option * 'a t
    val is_empty : 'a t -> bool
    val mem : key -> 'a t -> bool
    val equal : ('a -> 'a -> bool) -> 'a t -> 'a t -> bool
    val compare : ('a -> 'a -> int) -> 'a t -> 'a t -> int
    val for_all : (key -> 'a -> bool) -> 'a t -> bool
    val exists : (key -> 'a -> bool) -> 'a t -> bool
    val to_list : 'a t -> (key * 'a) list
    val of_list : (key * 'a) list -> 'a t
    val to_seq : 'a t -> (key * 'a) Stdlib.Seq.t
    val to_rev_seq : 'a t -> (key * 'a) Stdlib.Seq.t
    val to_seq_from : key -> 'a t -> (key * 'a) Stdlib.Seq.t
    val add_seq : (key * 'a) Stdlib.Seq.t -> 'a t -> 'a t
    val of_seq : (key * 'a) Stdlib.Seq.t -> 'a t
    val fold_map : 'a t -> init:'b -> f:('b -> 'a -> 'b * 'c) -> 'b * 'c t
    val fold_mapi : 'a t -> init:'b -> f:(key -> 'b -> 'a -> 'b * 'c) -> 'b * 'c t
    val is_singleton_or_more : 'a t -> (key * 'a) IContainer.singleton_or_more
    val pp_key : IStdlib.PrettyPrintable.F.formatter -> key -> unit
    val pp : + pp_value:(IStdlib.PrettyPrintable.F.formatter -> 'a -> unit) -> + IStdlib.PrettyPrintable.F.formatter -> + 'a t -> + unit
    val sexp_of_t : ('a -> Sexplib.Sexp.t) -> 'a t -> Sexplib.Sexp.t
    val t_of_sexp : (Sexplib.Sexp.t -> 'a) -> Sexplib.Sexp.t -> 'a t
    val hash_fold_t : + (Base_internalhash_types.state -> 'a -> Base_internalhash_types.state) -> + Base_internalhash_types.state -> + 'a t -> + Base_internalhash_types.state
    diff --git a/odoc/next/infer/IStdlib/IString/Set/index.html b/odoc/next/infer/IStdlib/IString/Set/index.html new file mode 100644 index 00000000000..b1c06dbbfa8 --- /dev/null +++ b/odoc/next/infer/IStdlib/IString/Set/index.html @@ -0,0 +1,5 @@ + +Set (infer.IStdlib.IString.Set)

    Module IString.Set

    include PrettyPrintable.PPSet with type elt = string
    include Stdlib.Set.S with type elt = string
    type elt = string
    type t
    val empty : t
    val add : elt -> t -> t
    val singleton : elt -> t
    val remove : elt -> t -> t
    val union : t -> t -> t
    val inter : t -> t -> t
    val disjoint : t -> t -> bool
    val diff : t -> t -> t
    val cardinal : t -> int
    val elements : t -> elt list
    val min_elt : t -> elt
    val min_elt_opt : t -> elt option
    val max_elt : t -> elt
    val max_elt_opt : t -> elt option
    val choose : t -> elt
    val choose_opt : t -> elt option
    val find : elt -> t -> elt
    val find_opt : elt -> t -> elt option
    val find_first : (elt -> bool) -> t -> elt
    val find_first_opt : (elt -> bool) -> t -> elt option
    val find_last : (elt -> bool) -> t -> elt
    val find_last_opt : (elt -> bool) -> t -> elt option
    val iter : (elt -> unit) -> t -> unit
    val fold : (elt -> 'acc -> 'acc) -> t -> 'acc -> 'acc
    val map : (elt -> elt) -> t -> t
    val filter : (elt -> bool) -> t -> t
    val filter_map : (elt -> elt option) -> t -> t
    val partition : (elt -> bool) -> t -> t * t
    val split : elt -> t -> t * bool * t
    val is_empty : t -> bool
    val mem : elt -> t -> bool
    val equal : t -> t -> bool
    val compare : t -> t -> int
    val subset : t -> t -> bool
    val for_all : (elt -> bool) -> t -> bool
    val exists : (elt -> bool) -> t -> bool
    val to_list : t -> elt list
    val of_list : elt list -> t
    val to_seq_from : elt -> t -> elt Stdlib.Seq.t
    val to_seq : t -> elt Stdlib.Seq.t
    val to_rev_seq : t -> elt Stdlib.Seq.t
    val add_seq : elt Stdlib.Seq.t -> t -> t
    val of_seq : elt Stdlib.Seq.t -> t
    val is_singleton_or_more : t -> elt IContainer.singleton_or_more
    include PrettyPrintable.PrintableType with type t := t
    val pp : IStdlib.PrettyPrintable.F.formatter -> t -> unit
    val pp_hov : IStdlib.PrettyPrintable.F.formatter -> t -> unit
    val pp_element : IStdlib.PrettyPrintable.F.formatter -> elt -> unit
    include IStdlib.IStd.Sexpable with type t := t
    val t_of_sexp : Sexplib0__.Sexp.t -> t
    val sexp_of_t : t -> Sexplib0__.Sexp.t
    val hash_fold_t : + Base_internalhash_types.state -> + t -> + Base_internalhash_types.state
    diff --git a/odoc/next/infer/IStdlib/IString/index.html b/odoc/next/infer/IStdlib/IString/index.html new file mode 100644 index 00000000000..a5e0148a10e --- /dev/null +++ b/odoc/next/infer/IStdlib/IString/index.html @@ -0,0 +1,2 @@ + +IString (infer.IStdlib.IString)

    Module IStdlib.IString

    module Map : PrettyPrintable.HashSexpPPMap with type key = string
    module Set : PrettyPrintable.HashSexpPPSet with type elt = string
    module Hash : Stdlib.Hashtbl.S with type key = string
    diff --git a/odoc/next/infer/IStdlib/PrettyPrintable/MakeConcurrentMap/index.html b/odoc/next/infer/IStdlib/PrettyPrintable/MakeConcurrentMap/index.html new file mode 100644 index 00000000000..dc20275f2a5 --- /dev/null +++ b/odoc/next/infer/IStdlib/PrettyPrintable/MakeConcurrentMap/index.html @@ -0,0 +1,2 @@ + +MakeConcurrentMap (infer.IStdlib.PrettyPrintable.MakeConcurrentMap)

    Module PrettyPrintable.MakeConcurrentMap

    a simple thread safe map that uses an atomic reference to a persistent map plus a mutex to sequentialize updates

    Parameters

    module Map : Stdlib.Map.S

    Signature

    type key = Map.key
    type 'a t
    val empty : unit -> 'a t
    val clear : 'a t -> unit
    val add : 'a t -> key -> 'a -> unit
    val filter : 'a t -> (key -> 'a -> bool) -> unit
    val find_opt : 'a t -> key -> 'a option
    val remove : 'a t -> key -> unit
    diff --git a/odoc/next/infer/IStdlib/PrettyPrintable/index.html b/odoc/next/infer/IStdlib/PrettyPrintable/index.html index 388c75b0d8d..71d6777252f 100644 --- a/odoc/next/infer/IStdlib/PrettyPrintable/index.html +++ b/odoc/next/infer/IStdlib/PrettyPrintable/index.html @@ -16,4 +16,6 @@ PPMonoMap with type key = Ord.t and type value = Val.t
    module type PrintableRankedType = sig ... end
    module type PPUniqRankSet = sig ... end

    set where at most one element of a given rank can be present

    + PPUniqRankSet with type elt = Val.t and type rank = Rank.t
    module type ConcurrentMap = sig ... end
    module MakeConcurrentMap + (Map : Stdlib.Map.S) : + ConcurrentMap with type key = Map.key

    a simple thread safe map that uses an atomic reference to a persistent map plus a mutex to sequentialize updates

    diff --git a/odoc/next/infer/IStdlib/PrettyPrintable/module-type-ConcurrentMap/index.html b/odoc/next/infer/IStdlib/PrettyPrintable/module-type-ConcurrentMap/index.html new file mode 100644 index 00000000000..8791b8d6b05 --- /dev/null +++ b/odoc/next/infer/IStdlib/PrettyPrintable/module-type-ConcurrentMap/index.html @@ -0,0 +1,2 @@ + +ConcurrentMap (infer.IStdlib.PrettyPrintable.ConcurrentMap)

    Module type PrettyPrintable.ConcurrentMap

    type key
    type 'a t
    val empty : unit -> 'a t
    val clear : 'a t -> unit
    val add : 'a t -> key -> 'a -> unit
    val filter : 'a t -> (key -> 'a -> bool) -> unit
    val find_opt : 'a t -> key -> 'a option
    val remove : 'a t -> key -> unit
    diff --git a/odoc/next/infer/Pulselib/PulseAbductiveDomain/CanonValue/Attributes/index.html b/odoc/next/infer/Pulselib/PulseAbductiveDomain/CanonValue/Attributes/index.html index 6c5e9998b4d..5381c0cfac7 100644 --- a/odoc/next/infer/Pulselib/PulseAbductiveDomain/CanonValue/Attributes/index.html +++ b/odoc/next/infer/Pulselib/PulseAbductiveDomain/CanonValue/Attributes/index.html @@ -2,7 +2,11 @@ Attributes (infer.Pulselib.PulseAbductiveDomain.CanonValue.Attributes)

    Module CanonValue.Attributes

    include Ppx_compare_lib.Comparable.S with type t := t
    val compare : t Base__Ppx_compare_lib.compare
    include Ppx_compare_lib.Equal.S with type t := t
    val equal : t Base__Ppx_compare_lib.equal
    val yojson_of_t : t -> Ppx_yojson_conv_lib.Yojson.Safe.t
    val pp : Pulselib.PulseBaseAddressAttributes.F.formatter -> t -> unit
    val empty : t
    val filter : (t -> Pulselib.PulseBasicInterface.Attributes.t -> bool) -> t -> t
    val filter_with_discarded_addrs : (t -> bool) -> t -> - t * Pulselib.PulseBasicInterface.AbstractValue.t list
    val find_opt : t -> t -> Pulselib.PulseBasicInterface.Attributes.t option
    val find_opt : t -> t -> Pulselib.PulseBasicInterface.Attributes.t option
    val allocate : Pulselib.PulseBasicInterface.Attribute.allocator -> t -> IBase.Location.t -> diff --git a/odoc/next/infer/Pulselib/PulseAbductiveDomain/index.html b/odoc/next/infer/Pulselib/PulseAbductiveDomain/index.html index 2702844b05d..d07b71d176d 100644 --- a/odoc/next/infer/Pulselib/PulseAbductiveDomain/index.html +++ b/odoc/next/infer/Pulselib/PulseAbductiveDomain/index.html @@ -1,5 +1,9 @@ -PulseAbductiveDomain (infer.Pulselib.PulseAbductiveDomain)

    Module Pulselib.PulseAbductiveDomain

    module F = Stdlib.Format
    module BaseDomain = PulseBaseDomain
    module Decompiler = PulseDecompiler
    module DecompilerExpr = PulseDecompilerExpr
    module PathContext = PulsePathContext

    Abductive, value-normalizing layer on top of BaseDomain

    The operations in this module take care of two things that are important for the safety of domain operations:

    1. Propagate operations on the current state to the pre-condition when necessary. This is the "abductive" part of the domain and follows the principles of biabduction as laid out in *Compositional Shape Analysis by Means of Bi-Abduction*, JACM, 2011, https://doi.org/10.1145/2049697.2049700. Simply put, a read from a memory location that is reachable from the precondition for the first time is taken to mean that this memory location had better been allocated since the beginning of the function for the operation to be safe, hence we "abduce" that this was the case and add it to the pre-condition (unless we already know that address to be invalid of course).

    2. Normalize values (AbstractValue.t) in and out of the state according to their canonical representatives as per the current path condition. The idea is that one can ask about any abstract value and functions in this API will normalize it as needed first before querying the abstract state, and normalize any value found in the abstract state as needed too. For example, values in the raw map corresponding to the memory are not necessarily normalized at all times but the API allows one to pretend they are by normalizing them on the fly. On the other hand, *keys* in the memory map are always normalized so values must be normalized before being looked up in the map and this module takes care of that transparently too. See also PulseCanonValue.

    module type BaseDomainSig = sig ... end

    signature common to the "normal" Domain, representing the post at the current program point, and the inverted PreDomain, representing the inferred pre-condition

    The post abstract state at each program point, or current state.

    The inferred pre-condition at each program point, biabduction style.

    type t = private {
    1. post : PostDomain.t;
      (*

      state at the current program point

      *)
    2. pre : PreDomain.t;
      (*

      inferred procedure pre-condition leading to the current program point

      *)
    3. path_condition : Pulselib.PulseBasicInterface.Formula.t;
      (*

      arithmetic facts true along the path (holding for both pre and post since abstract values are immutable)

      *)
    4. decompiler : Decompiler.t;
    5. topl : PulseTopl.state;
      (*

      state at of the Topl monitor at the current program point, when Topl is enabled

      *)
    6. need_dynamic_type_specialization : Pulselib.PulseBasicInterface.AbstractValue.Set.t;
      (*

      a set of abstract values that are used as receiver of method calls in the instructions reached so far

      *)
    7. transitive_info : Pulselib.PulseBasicInterface.TransitiveInfo.t;
      (*

      record transitive information inter-procedurally

      *)
    8. recursive_calls : PulseMutualRecursion.Set.t;
    9. skipped_calls : Pulselib.PulseBasicInterface.SkippedCalls.t;
      (*

      metadata: procedure calls for which no summary was found

      *)
    }

    pre/post on a single program path

    include Ppx_compare_lib.Equal.S with type t := t
    val equal : t Base__Ppx_compare_lib.equal
    val leq : lhs:t -> rhs:t -> bool
    val pp : Stdlib.Format.formatter -> t -> unit
    val mk_initial : IR.Tenv.t -> IR.ProcAttributes.t -> t
    val mk_join_state : +PulseAbductiveDomain (infer.Pulselib.PulseAbductiveDomain)

    Module Pulselib.PulseAbductiveDomain

    module F = Stdlib.Format
    module BaseDomain = PulseBaseDomain
    module Decompiler = PulseDecompiler
    module DecompilerExpr = PulseDecompilerExpr
    module PathContext = PulsePathContext

    Abductive, value-normalizing layer on top of BaseDomain

    The operations in this module take care of two things that are important for the safety of domain operations:

    1. Propagate operations on the current state to the pre-condition when necessary. This is the "abductive" part of the domain and follows the principles of biabduction as laid out in *Compositional Shape Analysis by Means of Bi-Abduction*, JACM, 2011, https://doi.org/10.1145/2049697.2049700. Simply put, a read from a memory location that is reachable from the precondition for the first time is taken to mean that this memory location had better been allocated since the beginning of the function for the operation to be safe, hence we "abduce" that this was the case and add it to the pre-condition (unless we already know that address to be invalid of course).

    2. Normalize values (AbstractValue.t) in and out of the state according to their canonical representatives as per the current path condition. The idea is that one can ask about any abstract value and functions in this API will normalize it as needed first before querying the abstract state, and normalize any value found in the abstract state as needed too. For example, values in the raw map corresponding to the memory are not necessarily normalized at all times but the API allows one to pretend they are by normalizing them on the fly. On the other hand, *keys* in the memory map are always normalized so values must be normalized before being looked up in the map and this module takes care of that transparently too. See also PulseCanonValue.

    module type BaseDomainSig = sig ... end

    signature common to the "normal" Domain, representing the post at the current program point, and the inverted PreDomain, representing the inferred pre-condition

    The post abstract state at each program point, or current state.

    The inferred pre-condition at each program point, biabduction style.

    type t = private {
    1. post : PostDomain.t;
      (*

      state at the current program point

      *)
    2. pre : PreDomain.t;
      (*

      inferred procedure pre-condition leading to the current program point

      *)
    3. path_condition : Pulselib.PulseBasicInterface.Formula.t;
      (*

      arithmetic facts true along the path (holding for both pre and post since abstract values are immutable)

      *)
    4. decompiler : Decompiler.t;
    5. topl : PulseTopl.state;
      (*

      state at of the Topl monitor at the current program point, when Topl is enabled

      *)
    6. need_dynamic_type_specialization : Pulselib.PulseBasicInterface.AbstractValue.Set.t;
      (*

      a set of abstract values that are used as receiver of method calls in the instructions reached so far

      *)
    7. transitive_info : Pulselib.PulseBasicInterface.TransitiveInfo.t;
      (*

      record transitive information inter-procedurally

      *)
    8. recursive_calls : PulseMutualRecursion.Set.t;
    9. skipped_calls : Pulselib.PulseBasicInterface.SkippedCalls.t;
      (*

      metadata: procedure calls for which no summary was found

      *)
    }

    pre/post on a single program path

    include Ppx_compare_lib.Equal.S with type t := t
    val equal : t Base__Ppx_compare_lib.equal
    val leq : lhs:t -> rhs:t -> bool
    val pp : Stdlib.Format.formatter -> t -> unit
    val mk_initial : IR.Tenv.t -> IR.ProcAttributes.t -> t
    val are_same_values_as_pre_formals : + IR.Procdesc.t -> + Pulselib.PulseBasicInterface.AbstractValue.t list -> + t -> + bool
    val add_recursive_call : IBase.Location.t -> IR.Procname.t -> t -> t
    val add_recursive_calls : PulseMutualRecursion.Set.t -> t -> t
    val add_skipped_call : + t
    val add_recursive_call : + IBase.Location.t -> + IR.Procname.t -> + Pulselib.PulseBasicInterface.AbstractValue.t list -> + t -> + t
    val add_recursive_calls : PulseMutualRecursion.Set.t -> t -> t
    val add_skipped_call : IR.Procname.t -> Pulselib.PulseBasicInterface.Trace.t -> t -> diff --git a/odoc/next/infer/Pulselib/PulseAccessResult/index.html b/odoc/next/infer/Pulselib/PulseAccessResult/index.html index 6b8c5c7a07e..a2aeb2b36e0 100644 --- a/odoc/next/infer/Pulselib/PulseAccessResult/index.html +++ b/odoc/next/infer/Pulselib/PulseAccessResult/index.html @@ -1,5 +1,5 @@ -PulseAccessResult (infer.Pulselib.PulseAccessResult)

    Module Pulselib.PulseAccessResult

    module AbductiveDomain = PulseAbductiveDomain
    module DecompilerExpr = PulseDecompilerExpr
    module Diagnostic = PulseDiagnostic
    type error =
    1. | PotentialInvalidAccess of {
      1. astate : AbductiveDomain.t;
      2. address : DecompilerExpr.t;
      3. must_be_valid : Pulselib.PulseBasicInterface.Trace.t +PulseAccessResult (infer.Pulselib.PulseAccessResult)

        Module Pulselib.PulseAccessResult

        module AbductiveDomain = PulseAbductiveDomain
        module DecompilerExpr = PulseDecompilerExpr
        module Diagnostic = PulseDiagnostic
        module PathContext = PulsePathContext
        type error =
        1. | PotentialInvalidAccess of {
          1. astate : AbductiveDomain.t;
          2. address : DecompilerExpr.t;
          3. must_be_valid : Pulselib.PulseBasicInterface.Trace.t * Pulselib.PulseBasicInterface.Invalidation.must_be_valid_reason option;
          }
        2. | PotentialInvalidSpecializedCall of {
          1. astate : AbductiveDomain.t;
          2. specialized_type : IR.Typ.Name.t;
          3. trace : Pulselib.PulseBasicInterface.Trace.t;
          }
        3. | ReportableError of {
          1. astate : AbductiveDomain.t;
          2. diagnostic : Diagnostic.t;
          }
        4. | WithSummary of error * AbductiveDomain.Summary.t
          (*

          An error for which the summary corresponding to the abstract state has already been computed, to avoid having to compute the summary for a given abstract state multiple times. For convenience this is part of the error datatype but the invariant that an error within a WithSummary (error, summary) cannot itself be a WithSummary _.

          *)
        val astate_of_error : error -> AbductiveDomain.t
        type 'a t = ('a, error) PulseResult.t
      ]
    val of_result_f : ('a, error) IStdlib.IStd.result -> f:(error -> 'a) -> 'a t
    val of_result_f : + PathContext.t -> + ('a, error) IStdlib.IStd.result -> + f:(error -> 'a) -> + 'a t
    val of_error_f : error -> f:(error -> 'a) -> 'a t
    val of_abductive_summary_error : + AbductiveDomain.t t
    val of_error_f : PathContext.t -> error -> f:(error -> 'a) -> 'a t
    val of_abductive_summary_error : [< abductive_summary_error ] -> error * AbductiveDomain.Summary.t
    val of_abductive_result : ('a, [< abductive_error ]) IStdlib.IStd.result -> diff --git a/odoc/next/infer/Pulselib/PulseBaseAddressAttributes/index.html b/odoc/next/infer/Pulselib/PulseBaseAddressAttributes/index.html index d9f892cb490..9a093ff2ac4 100644 --- a/odoc/next/infer/Pulselib/PulseBaseAddressAttributes/index.html +++ b/odoc/next/infer/Pulselib/PulseBaseAddressAttributes/index.html @@ -7,7 +7,11 @@ t
    val filter_with_discarded_addrs : (Pulselib.PulseBasicInterface.AbstractValue.t -> bool) -> t -> - t * Pulselib.PulseBasicInterface.AbstractValue.t list
    val add_one : diff --git a/odoc/next/infer/Pulselib/PulseBaseAddressAttributes/module-type-S/index.html b/odoc/next/infer/Pulselib/PulseBaseAddressAttributes/module-type-S/index.html index e623ac3d5bf..b0dfc2babb4 100644 --- a/odoc/next/infer/Pulselib/PulseBaseAddressAttributes/module-type-S/index.html +++ b/odoc/next/infer/Pulselib/PulseBaseAddressAttributes/module-type-S/index.html @@ -5,7 +5,11 @@ t
    val filter_with_discarded_addrs : (key -> bool) -> t -> - t * Pulselib.PulseBasicInterface.AbstractValue.t list
    val find_opt : key -> t -> Pulselib.PulseBasicInterface.Attributes.t option
    val find_opt : key -> t -> Pulselib.PulseBasicInterface.Attributes.t option
    val allocate : Pulselib.PulseBasicInterface.Attribute.allocator -> key -> IBase.Location.t -> diff --git a/odoc/next/infer/Pulselib/PulseCallOperations/index.html b/odoc/next/infer/Pulselib/PulseCallOperations/index.html index 90983d3515e..eef4dd13ddd 100644 --- a/odoc/next/infer/Pulselib/PulseCallOperations/index.html +++ b/odoc/next/infer/Pulselib/PulseCallOperations/index.html @@ -13,9 +13,9 @@ * IR.Typ.t) list -> formals_opt:(IR.Pvar.t * IR.Typ.t) list option -> - call_kind:PulseOperations.call_kind -> + PulseOperations.call_kind -> + IR.CallFlags.t -> Pulselib.PulseDomainInterface.AbductiveDomain.t -> - ?call_flags:IR.CallFlags.t -> Pulselib.PulseDomainInterface.NonDisjDomain.t -> Pulselib.PulseDomainInterface.ExecutionDomain.t Pulselib.PulseDomainInterface.AccessResult.t diff --git a/odoc/next/infer/Pulselib/PulseCanonValue/Make/Attributes/index.html b/odoc/next/infer/Pulselib/PulseCanonValue/Make/Attributes/index.html index e02bc95a150..6f7dab4179a 100644 --- a/odoc/next/infer/Pulselib/PulseCanonValue/Make/Attributes/index.html +++ b/odoc/next/infer/Pulselib/PulseCanonValue/Make/Attributes/index.html @@ -2,7 +2,11 @@ Attributes (infer.Pulselib.PulseCanonValue.Make.Attributes)

    Module Make.Attributes

    include Ppx_compare_lib.Comparable.S with type t := t
    val compare : t Base__Ppx_compare_lib.compare
    include Ppx_compare_lib.Equal.S with type t := t
    val equal : t Base__Ppx_compare_lib.equal
    val yojson_of_t : t -> Ppx_yojson_conv_lib.Yojson.Safe.t
    val pp : Pulselib.PulseBaseAddressAttributes.F.formatter -> t -> unit
    val empty : t
    val filter : (t -> Pulselib.PulseBasicInterface.Attributes.t -> bool) -> t -> t
    val filter_with_discarded_addrs : (t -> bool) -> t -> - t * Pulselib.PulseBasicInterface.AbstractValue.t list
    val find_opt : t -> t -> Pulselib.PulseBasicInterface.Attributes.t option
    val find_opt : t -> t -> Pulselib.PulseBasicInterface.Attributes.t option
    val allocate : Pulselib.PulseBasicInterface.Attribute.allocator -> t -> IBase.Location.t -> diff --git a/odoc/next/infer/Pulselib/PulseCanonValue/module-type-S/Attributes/index.html b/odoc/next/infer/Pulselib/PulseCanonValue/module-type-S/Attributes/index.html index 5a26cdaa265..727b65d3ecf 100644 --- a/odoc/next/infer/Pulselib/PulseCanonValue/module-type-S/Attributes/index.html +++ b/odoc/next/infer/Pulselib/PulseCanonValue/module-type-S/Attributes/index.html @@ -2,7 +2,11 @@ Attributes (infer.Pulselib.PulseCanonValue.S.Attributes)

    Module S.Attributes

    include Ppx_compare_lib.Comparable.S with type t := t
    val compare : t Base__Ppx_compare_lib.compare
    include Ppx_compare_lib.Equal.S with type t := t
    val equal : t Base__Ppx_compare_lib.equal
    val yojson_of_t : t -> Ppx_yojson_conv_lib.Yojson.Safe.t
    val pp : Pulselib.PulseBaseAddressAttributes.F.formatter -> t -> unit
    val empty : t
    val filter : (t -> Pulselib.PulseBasicInterface.Attributes.t -> bool) -> t -> t
    val filter_with_discarded_addrs : (t -> bool) -> t -> - t * Pulselib.PulseBasicInterface.AbstractValue.t list
    val find_opt : t -> t -> Pulselib.PulseBasicInterface.Attributes.t option
    val find_opt : t -> t -> Pulselib.PulseBasicInterface.Attributes.t option
    val allocate : Pulselib.PulseBasicInterface.Attribute.allocator -> t -> IBase.Location.t -> diff --git a/odoc/next/infer/Pulselib/PulseDiagnostic/index.html b/odoc/next/infer/Pulselib/PulseDiagnostic/index.html index 166ac408f4b..fb5ece3114c 100644 --- a/odoc/next/infer/Pulselib/PulseDiagnostic/index.html +++ b/odoc/next/infer/Pulselib/PulseDiagnostic/index.html @@ -1,5 +1,5 @@ -PulseDiagnostic (infer.Pulselib.PulseDiagnostic)

    Module Pulselib.PulseDiagnostic

    module F = Stdlib.Format
    module Attribute = PulseAttribute
    module CallEvent = PulseCallEvent
    module ConfigName = OpenSource.FbPulseConfigName
    module DecompilerExpr = PulseDecompilerExpr
    module Invalidation = PulseInvalidation
    module TaintItem = PulseTaintItem
    module Trace = PulseTrace
    module TransitiveInfo = PulseTransitiveInfo
    module ValueHistory = PulseValueHistory
    type calling_context = (CallEvent.t * IBase.Location.t) list
    val compare_calling_context : calling_context -> calling_context -> int
    val equal_calling_context : calling_context -> calling_context -> bool
    type access_to_invalid_address = {
    1. calling_context : calling_context;
      (*

      the list of function calls leading to the issue being realised, in outermost-to-innermost order, which is an additional common prefix to the traces in the record

      *)
    2. invalid_address : DecompilerExpr.t;
    3. invalidation : Invalidation.t;
    4. invalidation_trace : Trace.t;
      (*

      assuming we are in the calling context, the trace leads to invalidation without further assumptions

      *)
    5. access_trace : Trace.t;
      (*

      assuming we are in the calling context, the trace leads to an access to the value invalidated in invalidation_trace without further assumptions

      *)
    6. must_be_valid_reason : Invalidation.must_be_valid_reason option;
    }
    val compare_access_to_invalid_address : +PulseDiagnostic (infer.Pulselib.PulseDiagnostic)

    Module Pulselib.PulseDiagnostic

    module F = Stdlib.Format
    module Attribute = PulseAttribute
    module CallEvent = PulseCallEvent
    module ConfigName = OpenSource.FbPulseConfigName
    module DecompilerExpr = PulseDecompilerExpr
    module Invalidation = PulseInvalidation
    module PathContext = PulsePathContext
    module TaintItem = PulseTaintItem
    module Trace = PulseTrace
    module TransitiveInfo = PulseTransitiveInfo
    module ValueHistory = PulseValueHistory
    type calling_context = (CallEvent.t * IBase.Location.t) list
    val compare_calling_context : calling_context -> calling_context -> int
    val equal_calling_context : calling_context -> calling_context -> bool
    type access_to_invalid_address = {
    1. calling_context : calling_context;
      (*

      the list of function calls leading to the issue being realised, in outermost-to-innermost order, which is an additional common prefix to the traces in the record

      *)
    2. invalid_address : DecompilerExpr.t;
    3. invalidation : Invalidation.t;
    4. invalidation_trace : Trace.t;
      (*

      assuming we are in the calling context, the trace leads to invalidation without further assumptions

      *)
    5. access_trace : Trace.t;
      (*

      assuming we are in the calling context, the trace leads to an access to the value invalidated in invalidation_trace without further assumptions

      *)
    6. must_be_valid_reason : Invalidation.must_be_valid_reason option;
    }
    val compare_access_to_invalid_address : access_to_invalid_address -> access_to_invalid_address -> int
    val equal_access_to_invalid_address : @@ -7,4 +7,4 @@ access_to_invalid_address -> bool
    val yojson_of_access_to_invalid_address : access_to_invalid_address -> - Ppx_yojson_conv_lib.Yojson.Safe.t
    module ErlangError : sig ... end
    module ReadUninitialized : sig ... end
    type flow_kind =
    1. | TaintedFlow
    2. | FlowToSink
    3. | FlowFromSource
    val equal_flow_kind : flow_kind -> flow_kind -> bool
    type retain_cycle_data = {
    1. expr : DecompilerExpr.t;
    2. location : IBase.Location.t option;
    3. trace : Trace.t option;
    }
    val equal_retain_cycle_data : retain_cycle_data -> retain_cycle_data -> bool
    type resource =
    1. | CSharpClass of IR.CSharpClassName.t
    2. | JavaClass of IR.JavaClassName.t
    3. | Awaitable
    4. | HackBuilderResource of IR.HackClassName.t
    5. | Memory of Attribute.allocator
    type t =
    1. | AccessToInvalidAddress of access_to_invalid_address
    2. | ConfigUsage of {
      1. pname : IR.Procname.t;
      2. config : ConfigName.t;
      3. branch_location : IBase.Location.t;
      4. location : IBase.Location.t;
      5. trace : Trace.t;
      }
    3. | ConstRefableParameter of {
      1. param : IR.Var.t;
      2. typ : IR.Typ.t;
      3. location : IBase.Location.t;
      }
    4. | DynamicTypeMismatch of {
      1. location : IBase.Location.t;
      }
    5. | ErlangError of ErlangError.t
    6. | HackCannotInstantiateAbstractClass of {
      1. type_name : IR.Typ.Name.t;
      2. trace : Trace.t;
      }
    7. | MutualRecursionCycle of {
      1. cycle : PulseMutualRecursion.t;
      2. location : IBase.Location.t;
      }
    8. | ReadonlySharedPtrParameter of {
      1. param : IR.Var.t;
      2. typ : IR.Typ.t;
      3. location : IBase.Location.t;
      4. used_locations : IBase.Location.t list;
      }
    9. | ReadUninitialized of ReadUninitialized.t
    10. | ResourceLeak of {
      1. resource : resource;
      2. allocation_trace : Trace.t;
      3. location : IBase.Location.t;
      }
    11. | RetainCycle of {
      1. values : retain_cycle_data list;
      2. location : IBase.Location.t;
      3. unknown_access_type : bool;
      }
    12. | StackVariableAddressEscape of {
      1. variable : IR.Var.t;
      2. history : ValueHistory.t;
      3. location : IBase.Location.t;
      }
    13. | TaintFlow of {
      1. expr : DecompilerExpr.t;
      2. source : TaintItem.t * ValueHistory.t;
      3. sink : TaintItem.t * Trace.t;
      4. location : IBase.Location.t;
      5. flow_kind : flow_kind;
      6. policy_description : string;
      7. policy_id : int;
      8. policy_privacy_effect : string option;
      9. report_as_issue_type : string option;
      10. report_as_category : string option;
      }
    14. | TransitiveAccess of {
      1. tag : string;
      2. description : string;
      3. call_trace : Trace.t;
      4. transitive_callees : TransitiveInfo.Callees.t;
      5. transitive_missed_captures : IR.Typ.Name.Set.t;
      }
    15. | UninitMethod of {
      1. callee : IR.Procname.t;
      2. history : ValueHistory.t;
      3. location : IBase.Location.t;
      }
    16. | UnnecessaryCopy of {
      1. copied_into : PulseAttribute.CopiedInto.t;
      2. source_typ : IR.Typ.t option;
      3. source_opt : DecompilerExpr.source_expr option;
      4. location : IBase.Location.t;
      5. copied_location : (IR.Procname.t * IBase.Location.t) option;
      6. location_instantiated : IBase.Location.t option;
      7. from : PulseAttribute.CopyOrigin.t;
      }

    an error to report to the user

    include Ppx_compare_lib.Equal.S with type t := t
    val equal : t Base__Ppx_compare_lib.equal
    val pp : F.formatter -> t -> unit
    val aborts_execution : t -> bool

    whether the presence of an error should abort the execution

    val get_message_and_suggestion : t -> string * string option
    val get_autofix : IR.Procdesc.t -> t -> ATDGenerated.Jsonbug_t.autofix option
    val get_location : t -> IBase.Location.t
    val get_location_instantiated : t -> IBase.Location.t option
    val get_copy_type : t -> IR.Typ.t option
    val get_issue_type : latent:bool -> t -> IBase.IssueType.t
    val get_trace : t -> Absint.Errlog.loc_trace
    + Ppx_yojson_conv_lib.Yojson.Safe.t
    module ErlangError : sig ... end
    module ReadUninitialized : sig ... end
    type flow_kind =
    1. | TaintedFlow
    2. | FlowToSink
    3. | FlowFromSource
    val equal_flow_kind : flow_kind -> flow_kind -> bool
    type retain_cycle_data = {
    1. expr : DecompilerExpr.t;
    2. location : IBase.Location.t option;
    3. trace : Trace.t option;
    }
    val equal_retain_cycle_data : retain_cycle_data -> retain_cycle_data -> bool
    type resource =
    1. | CSharpClass of IR.CSharpClassName.t
    2. | JavaClass of IR.JavaClassName.t
    3. | Awaitable
    4. | HackBuilderResource of IR.HackClassName.t
    5. | Memory of Attribute.allocator
    type t =
    1. | AccessToInvalidAddress of access_to_invalid_address
    2. | ConfigUsage of {
      1. pname : IR.Procname.t;
      2. config : ConfigName.t;
      3. branch_location : IBase.Location.t;
      4. location : IBase.Location.t;
      5. trace : Trace.t;
      }
    3. | ConstRefableParameter of {
      1. param : IR.Var.t;
      2. typ : IR.Typ.t;
      3. location : IBase.Location.t;
      }
    4. | DynamicTypeMismatch of {
      1. location : IBase.Location.t;
      }
    5. | ErlangError of ErlangError.t
    6. | HackCannotInstantiateAbstractClass of {
      1. type_name : IR.Typ.Name.t;
      2. trace : Trace.t;
      }
    7. | MutualRecursionCycle of {
      1. cycle : PulseMutualRecursion.t;
      2. location : IBase.Location.t;
      3. is_call_with_same_values : bool;
      }
    8. | ReadonlySharedPtrParameter of {
      1. param : IR.Var.t;
      2. typ : IR.Typ.t;
      3. location : IBase.Location.t;
      4. used_locations : IBase.Location.t list;
      }
    9. | ReadUninitialized of ReadUninitialized.t
    10. | ResourceLeak of {
      1. resource : resource;
      2. allocation_trace : Trace.t;
      3. location : IBase.Location.t;
      }
    11. | RetainCycle of {
      1. values : retain_cycle_data list;
      2. location : IBase.Location.t;
      3. unknown_access_type : bool;
      }
    12. | StackVariableAddressEscape of {
      1. variable : IR.Var.t;
      2. history : ValueHistory.t;
      3. location : IBase.Location.t;
      }
    13. | TaintFlow of {
      1. expr : DecompilerExpr.t;
      2. source : TaintItem.t * ValueHistory.t;
      3. sink : TaintItem.t * Trace.t;
      4. location : IBase.Location.t;
      5. flow_kind : flow_kind;
      6. policy_description : string;
      7. policy_id : int;
      8. policy_privacy_effect : string option;
      9. report_as_issue_type : string option;
      10. report_as_category : string option;
      }
    14. | TransitiveAccess of {
      1. tag : string;
      2. description : string;
      3. call_trace : Trace.t;
      4. transitive_callees : TransitiveInfo.Callees.t;
      5. transitive_missed_captures : IR.Typ.Name.Set.t;
      }
    15. | UninitMethod of {
      1. callee : IR.Procname.t;
      2. history : ValueHistory.t;
      3. location : IBase.Location.t;
      }
    16. | UnnecessaryCopy of {
      1. copied_into : PulseAttribute.CopiedInto.t;
      2. source_typ : IR.Typ.t option;
      3. source_opt : DecompilerExpr.source_expr option;
      4. location : IBase.Location.t;
      5. copied_location : (IR.Procname.t * IBase.Location.t) option;
      6. location_instantiated : IBase.Location.t option;
      7. from : PulseAttribute.CopyOrigin.t;
      }

    an error to report to the user

    include Ppx_compare_lib.Equal.S with type t := t
    val equal : t Base__Ppx_compare_lib.equal
    val pp : F.formatter -> t -> unit
    val aborts_execution : PathContext.t -> t -> bool

    whether the presence of an error should abort the execution

    val get_message_and_suggestion : t -> string * string option
    val get_autofix : IR.Procdesc.t -> t -> ATDGenerated.Jsonbug_t.autofix option
    val get_location : t -> IBase.Location.t
    val get_location_instantiated : t -> IBase.Location.t option
    val get_copy_type : t -> IR.Typ.t option
    val get_issue_type : latent:bool -> t -> IBase.IssueType.t
    val get_trace : t -> Absint.Errlog.loc_trace
    diff --git a/odoc/next/infer/Pulselib/PulseJoin/index.html b/odoc/next/infer/Pulselib/PulseJoin/index.html new file mode 100644 index 00000000000..f449abf2150 --- /dev/null +++ b/odoc/next/infer/Pulselib/PulseJoin/index.html @@ -0,0 +1,8 @@ + +PulseJoin (infer.Pulselib.PulseJoin)

    Module Pulselib.PulseJoin

    diff --git a/odoc/next/infer/Pulselib/PulseModelsDSL/Syntax/index.html b/odoc/next/infer/Pulselib/PulseModelsDSL/Syntax/index.html index 370e9a867e8..5cf62ee20d7 100644 --- a/odoc/next/infer/Pulselib/PulseModelsDSL/Syntax/index.html +++ b/odoc/next/infer/Pulselib/PulseModelsDSL/Syntax/index.html @@ -64,12 +64,22 @@ Pulselib.PulseBasicInterface.Access.t -> aval model_monad
    val load_access : ?no_access:bool -> + ?deref:bool -> aval -> Pulselib.PulseBasicInterface.Access.t -> aval model_monad
    val load : aval -> aval model_monad

    read the Dereference access from the value

    val and_dynamic_type_is : aval -> IR.Typ.t -> unit model_monad
    val get_dynamic_type : ask_specialization:bool -> aval -> - Pulselib.PulseBasicInterface.Formula.dynamic_type_data option model_monad
    val new_ : IR.Exp.t -> aval model_monad
    val constructor : IR.Typ.Name.t -> (string * aval) list -> aval model_monad

    constructor_dsl typ_name fields builds a fresh object of type typ_name and initializes its fields using list fields

    val remove_hack_builder_attributes : aval -> unit model_monad
    val fresh : ?more:string -> unit -> aval model_monad
    val fresh_nonneg : ?more:string -> unit -> aval model_monad
    val write_field : ref:aval -> IR.Fieldname.t -> aval -> unit model_monad
    val store_field : ref:aval -> IR.Fieldname.t -> aval -> unit model_monad
    val store : ref:aval -> aval -> unit model_monad
    val new_ : IR.Exp.t -> aval model_monad
    val constructor : + ?deref:bool -> + IR.Typ.Name.t -> + (string * aval) list -> + aval model_monad

    constructor_dsl typ_name fields builds a fresh object of type typ_name and initializes its fields using list fields

    val remove_hack_builder_attributes : aval -> unit model_monad
    val fresh : ?more:string -> unit -> aval model_monad
    val fresh_nonneg : ?more:string -> unit -> aval model_monad
    val write_field : ref:aval -> IR.Fieldname.t -> aval -> unit model_monad
    val store_field : + ?deref:bool -> + ref:aval -> + IR.Fieldname.t -> + aval -> + unit model_monad
    val store : ref:aval -> aval -> unit model_monad

    Return the fields we know about. There may be more, so use with caution

    PulseFormula operations

    val prune_eq : aval -> aval -> unit model_monad
    val prune_eq_int : aval -> IR.IntLit.t -> unit model_monad
    val prune_eq_string : aval -> string -> unit model_monad
    val prune_ne_string : aval -> string -> unit model_monad
    val prune_eq_zero : aval -> unit model_monad
    val prune_positive : aval -> unit model_monad
    val prune_lt : aval -> aval -> unit model_monad
    val prune_lt_int : aval -> IR.IntLit.t -> unit model_monad
    val prune_le : aval -> aval -> unit model_monad
    val prune_gt : aval -> aval -> unit model_monad
    val prune_gt_int : aval -> IR.IntLit.t -> unit model_monad
    val prune_ge : aval -> aval -> unit model_monad
    val prune_ge_int : aval -> IR.IntLit.t -> unit model_monad
    val prune_ne : aval -> aval -> unit model_monad
    val prune_ne_int : aval -> IR.IntLit.t -> unit model_monad
    val prune_ne_zero : aval -> unit model_monad
    val and_eq_int : aval -> IR.IntLit.t -> unit model_monad
    val and_eq : aval -> aval -> unit model_monad
    val and_equal_instanceof : aval -> diff --git a/odoc/next/infer/Pulselib/PulseModelsPython/index.html b/odoc/next/infer/Pulselib/PulseModelsPython/index.html new file mode 100644 index 00000000000..05cffba5f65 --- /dev/null +++ b/odoc/next/infer/Pulselib/PulseModelsPython/index.html @@ -0,0 +1,2 @@ + +PulseModelsPython (infer.Pulselib.PulseModelsPython)

    Module Pulselib.PulseModelsPython

    val matchers : PulseModelsImport.matcher list
    diff --git a/odoc/next/infer/Pulselib/PulseMutualRecursion/index.html b/odoc/next/infer/Pulselib/PulseMutualRecursion/index.html index b701e173e1d..f2742f7b083 100644 --- a/odoc/next/infer/Pulselib/PulseMutualRecursion/index.html +++ b/odoc/next/infer/Pulselib/PulseMutualRecursion/index.html @@ -1,2 +1,13 @@ -PulseMutualRecursion (infer.Pulselib.PulseMutualRecursion)

    Module Pulselib.PulseMutualRecursion

    module F = Stdlib.Format
    type t

    the trace represents the start of a cycle but isn't a cycle yet, it's a sequence of calls that end where ondemand returned no summary due to mutual recursion; these proto-cycles get bubbled the cyclic call stack until the cycle is closed again

    include Ppx_compare_lib.Equal.S with type t := t
    val equal : t Base__Ppx_compare_lib.equal

    a trace of length 1

    val get_inner_call : t -> IR.Procname.t

    the "initial", innermost call in the cycle

    val get_outer_location : t -> IBase.Location.t

    the location of the first call in the cycle

    val add_call : IR.Procname.t -> IBase.Location.t -> t -> t
    val iter_rotations : t -> f:(t -> unit) -> unit
    val pp : F.formatter -> t -> unit
    val get_error_message : t -> string
    val to_errlog : t -> Absint.Errlog.loc_trace
    module Set : IStdlib.PrettyPrintable.PPSet with type elt = t
    +PulseMutualRecursion (infer.Pulselib.PulseMutualRecursion)

    Module Pulselib.PulseMutualRecursion

    module F = Stdlib.Format
    type t

    the trace represents the start of a cycle but isn't a cycle yet, it's a sequence of calls that end where ondemand returned no summary due to mutual recursion; these proto-cycles get bubbled the cyclic call stack until the cycle is closed again

    include Ppx_compare_lib.Equal.S with type t := t
    val equal : t Base__Ppx_compare_lib.equal

    a trace of length 1

    val get_inner_call : t -> IR.Procname.t

    the "initial", innermost call in the cycle

    val get_outer_location : t -> IBase.Location.t

    the location of the first call in the cycle

    val iter_rotations : t -> f:(t -> unit) -> unit
    val pp : F.formatter -> t -> unit
    val get_error_message : t -> is_call_with_same_values:bool -> string
    val to_errlog : t -> is_call_with_same_values:bool -> Absint.Errlog.loc_trace
    module Set : IStdlib.PrettyPrintable.PPSet with type elt = t
    diff --git a/odoc/next/infer/Pulselib/PulseNonDisjunctiveDomain/Summary/index.html b/odoc/next/infer/Pulselib/PulseNonDisjunctiveDomain/Summary/index.html index 782df809774..4ddfb153665 100644 --- a/odoc/next/infer/Pulselib/PulseNonDisjunctiveDomain/Summary/index.html +++ b/odoc/next/infer/Pulselib/PulseNonDisjunctiveDomain/Summary/index.html @@ -1,4 +1,6 @@ Summary (infer.Pulselib.PulseNonDisjunctiveDomain.Summary)

    Module PulseNonDisjunctiveDomain.Summary

    type t = summary
    val bottom : t
    val pp : F.formatter -> t -> unit
    val join : t -> t -> t
    val get_transitive_info_if_not_top : t -> - Pulselib.PulseBasicInterface.TransitiveInfo.t option
    val has_dropped_disjuncts : t -> bool
    + Pulselib.PulseBasicInterface.TransitiveInfo.t option
    val has_dropped_disjuncts : t -> bool
    diff --git a/odoc/next/infer/Pulselib/PulseNonDisjunctiveDomain/index.html b/odoc/next/infer/Pulselib/PulseNonDisjunctiveDomain/index.html index a4474e9bdf7..e88a0509634 100644 --- a/odoc/next/infer/Pulselib/PulseNonDisjunctiveDomain/index.html +++ b/odoc/next/infer/Pulselib/PulseNonDisjunctiveDomain/index.html @@ -1,10 +1,13 @@ -PulseNonDisjunctiveDomain (infer.Pulselib.PulseNonDisjunctiveDomain)

    Module Pulselib.PulseNonDisjunctiveDomain

    module F = Stdlib.Format
    module BaseMemory = PulseBaseMemory
    module DecompilerExpr = PulseDecompilerExpr
    module ExecutionDomain = PulseExecutionDomain
    module PathContext = PulsePathContext
    type copy_spec_t =
    1. | Copied of {
      1. source_typ : IR.Typ.t option;
      2. source_opt : DecompilerExpr.source_expr option;
      3. node : IR.Procdesc.Node.t;
      4. location : IBase.Location.t;
      5. copied_location : (IR.Procname.t * IBase.Location.t) option;
      6. heap : BaseMemory.t;
      7. from : Pulselib.PulseBasicInterface.Attribute.CopyOrigin.t;
      8. timestamp : Pulselib.PulseBasicInterface.Timestamp.t;
      }
    2. | Modified of {
      1. source_typ : IR.Typ.t option;
      2. source_opt : DecompilerExpr.source_expr option;
      3. node : IR.Procdesc.Node.t;
      4. location : IBase.Location.t;
      5. copied_location : (IR.Procname.t * IBase.Location.t) option;
      6. from : Pulselib.PulseBasicInterface.Attribute.CopyOrigin.t;
      7. copied_timestamp : Pulselib.PulseBasicInterface.Timestamp.t;
      }
    type parameter_spec_t =
    1. | Unmodified of {
      1. typ : IR.Typ.t;
      2. location : IBase.Location.t;
      3. heap : BaseMemory.t;
      }
    2. | Modified
    include Absint.AbstractDomain.WithBottomTop
    include Absint.AbstractDomain.S
    include Absint.AbstractDomain.Comparable
    include IStdlib.PrettyPrintable.PrintableType
    type t
    val pp : IStdlib.PrettyPrintable.F.formatter -> t -> unit
    val leq : lhs:t -> rhs:t -> bool

    the implication relation: lhs <= rhs means lhs |- rhs

    val join : t -> t -> t
    val widen : prev:t -> next:t -> num_iters:int -> t
    val bottom : t
    val is_bottom : t -> bool
    val top : t
    val is_top : t -> bool
    val exec : +PulseNonDisjunctiveDomain (infer.Pulselib.PulseNonDisjunctiveDomain)

    Module Pulselib.PulseNonDisjunctiveDomain

    module F = Stdlib.Format
    module AbductiveDomain = PulseAbductiveDomain
    module BaseMemory = PulseBaseMemory
    module DecompilerExpr = PulseDecompilerExpr
    module ExecutionDomain = PulseExecutionDomain
    module PathContext = PulsePathContext
    type copy_spec_t =
    1. | Copied of {
      1. source_typ : IR.Typ.t option;
      2. source_opt : DecompilerExpr.source_expr option;
      3. node : IR.Procdesc.Node.t;
      4. location : IBase.Location.t;
      5. copied_location : (IR.Procname.t * IBase.Location.t) option;
      6. heap : BaseMemory.t;
      7. from : Pulselib.PulseBasicInterface.Attribute.CopyOrigin.t;
      8. timestamp : Pulselib.PulseBasicInterface.Timestamp.t;
      }
    2. | Modified of {
      1. source_typ : IR.Typ.t option;
      2. source_opt : DecompilerExpr.source_expr option;
      3. node : IR.Procdesc.Node.t;
      4. location : IBase.Location.t;
      5. copied_location : (IR.Procname.t * IBase.Location.t) option;
      6. from : Pulselib.PulseBasicInterface.Attribute.CopyOrigin.t;
      7. copied_timestamp : Pulselib.PulseBasicInterface.Timestamp.t;
      }
    type parameter_spec_t =
    1. | Unmodified of {
      1. typ : IR.Typ.t;
      2. location : IBase.Location.t;
      3. heap : BaseMemory.t;
      }
    2. | Modified
    include Absint.AbstractDomain.WithBottomTop
    include Absint.AbstractDomain.S
    include Absint.AbstractDomain.Comparable
    include IStdlib.PrettyPrintable.PrintableType
    type t
    val pp : IStdlib.PrettyPrintable.F.formatter -> t -> unit
    val leq : lhs:t -> rhs:t -> bool

    the implication relation: lhs <= rhs means lhs |- rhs

    val join : t -> t -> t
    val widen : prev:t -> next:t -> num_iters:int -> t
    val bottom : t
    val is_bottom : t -> bool
    val top : t
    val is_top : t -> bool
    val exec : t -> exec_instr: (((ExecutionDomain.t * PathContext.t) * t) -> (ExecutionDomain.t * PathContext.t) list * t) -> - t
    val pp_with_kind : IStdlib.Pp.print_kind -> F.formatter -> t -> unit
    type summary
    val make_summary : IR.ProcAttributes.t -> IBase.Location.t -> t -> summary
    module Summary : sig ... end
    val add_var : + t
    val astate_is_bottom : t -> bool
    val for_disjunct_exec_instr : t -> t
    val pp_with_kind : IStdlib.Pp.print_kind -> F.formatter -> t -> unit
    type summary
    val make_summary : IR.ProcAttributes.t -> IBase.Location.t -> t -> summary
    module Summary : sig ... end
    val add_var : Pulselib.PulseBasicInterface.Attribute.CopiedInto.t -> source_addr_opt:Pulselib.PulseBasicInterface.AbstractValue.t option -> copy_spec_t -> diff --git a/odoc/next/infer/Pulselib/PulseOperations/index.html b/odoc/next/infer/Pulselib/PulseOperations/index.html index 9616623ea13..b0f1487ae36 100644 --- a/odoc/next/infer/Pulselib/PulseOperations/index.html +++ b/odoc/next/infer/Pulselib/PulseOperations/index.html @@ -109,7 +109,7 @@ IR.Exp.t -> t -> (t * IR.Procname.t option) Pulselib.PulseDomainInterface.AccessResult.t - Pulselib.PulseBasicInterface.SatUnsat.t
    val hack_python_propagates_type_on_load : + Pulselib.PulseBasicInterface.SatUnsat.t
    type call_kind = [
    1. | `Closure of (IR.Exp.t * IR.CapturedVar.t) list
    2. | `Var of IR.Ident.t
    3. | `ResolvedProcname
    ]
    val get_captured_actuals : + t Pulselib.PulseDomainInterface.AccessResult.t
    type call_kind =
    1. | ClosureCall of (IR.Exp.t * IR.CapturedVar.t) list
    2. | VarCall of IR.Ident.t
    3. | ResolvedCall
    val get_captured_actuals : IR.Procname.t -> Pulselib.PulseDomainInterface.PathContext.t -> IBase.Location.t -> + call_kind -> captured_formals:IR.CapturedVar.t list -> - call_kind:call_kind -> actuals: ((Pulselib.PulseBasicInterface.AbstractValue.t * Pulselib.PulseBasicInterface.ValueHistory.t) diff --git a/odoc/next/infer/Pulselib/PulsePathContext/index.html b/odoc/next/infer/Pulselib/PulsePathContext/index.html index b2300604125..d68a798e678 100644 --- a/odoc/next/infer/Pulselib/PulsePathContext/index.html +++ b/odoc/next/infer/Pulselib/PulsePathContext/index.html @@ -1,2 +1,2 @@ -PulsePathContext (infer.Pulselib.PulsePathContext)

    Module Pulselib.PulsePathContext

    type t = {
    1. timestamp : Pulselib.PulseBasicInterface.Timestamp.t;
      (*

      step number in an intra-procedural analysis

      *)
    }
    include Ppx_compare_lib.Comparable.S with type t := t
    val compare : t Base__Ppx_compare_lib.compare
    include Ppx_compare_lib.Equal.S with type t := t
    val equal : t Base__Ppx_compare_lib.equal
    include Absint.AbstractDomain.Disjunct with type t := t
    include Absint.AbstractDomain.Comparable with type t := t
    include IStdlib.PrettyPrintable.PrintableType with type t := t
    val pp : IStdlib.PrettyPrintable.F.formatter -> t -> unit
    val leq : lhs:t -> rhs:t -> bool

    the implication relation: lhs <= rhs means lhs |- rhs

    val equal_fast : t -> t -> bool

    equal_fast x y must imply x <=> y; it's a good idea for this function to be "fast", e.g. not depend on the size of its input

    val is_normal : t -> bool

    test if the abstract state represents exactly concrete states

    val is_exceptional : t -> bool

    test if the abstract state represents exactly exceptional concrete states

    val is_executable : t -> bool

    test if the abstract state represents executable states, e.g. ContinueProgram or ExceptionRaised.

    val exceptional_to_normal : t -> t

    convert all exceptional states into normal states (used when reaching a handler)

    val join : t -> t -> t
    val initial : t
    val post_exec_instr : t -> t

    call this after each step of the symbolic execution to update the path information

    +PulsePathContext (infer.Pulselib.PulsePathContext)

    Module Pulselib.PulsePathContext

    type t = {
    1. timestamp : Pulselib.PulseBasicInterface.Timestamp.t;
      (*

      step number in an intra-procedural analysis

      *)
    2. is_non_disj : bool;
      (*

      whether we are currently executing the abstract state inside the non-disjunctive (=over-approximate) part of the state

      *)
    }
    include Ppx_compare_lib.Comparable.S with type t := t
    val compare : t Base__Ppx_compare_lib.compare
    include Ppx_compare_lib.Equal.S with type t := t
    val equal : t Base__Ppx_compare_lib.equal
    include Absint.AbstractDomain.Disjunct with type t := t
    include Absint.AbstractDomain.Comparable with type t := t
    include IStdlib.PrettyPrintable.PrintableType with type t := t
    val pp : IStdlib.PrettyPrintable.F.formatter -> t -> unit
    val leq : lhs:t -> rhs:t -> bool

    the implication relation: lhs <= rhs means lhs |- rhs

    val equal_fast : t -> t -> bool

    equal_fast x y must imply x <=> y; it's a good idea for this function to be "fast", e.g. not depend on the size of its input

    val is_normal : t -> bool

    test if the abstract state represents exactly concrete states

    val is_exceptional : t -> bool

    test if the abstract state represents exactly exceptional concrete states

    val is_executable : t -> bool

    test if the abstract state represents executable states, e.g. ContinueProgram or ExceptionRaised.

    val exceptional_to_normal : t -> t

    convert all exceptional states into normal states (used when reaching a handler)

    val join : t -> t -> t
    val initial : t
    val post_exec_instr : t -> t

    call this after each step of the symbolic execution to update the path information

    diff --git a/odoc/next/infer/Pulselib/PulseReport/index.html b/odoc/next/infer/Pulselib/PulseReport/index.html index b6ae7d62b8e..d77614a8780 100644 --- a/odoc/next/infer/Pulselib/PulseReport/index.html +++ b/odoc/next/infer/Pulselib/PulseReport/index.html @@ -6,21 +6,25 @@ Pulselib.PulseDomainInterface.Diagnostic.t -> unit

    None means that the execution can continue but we could not compute the continuation state (because this only takes a AccessResult.error, which doesn't have the ok state)

    val report_exec_results : _ Absint.InterproceduralAnalysis.t -> + Pulselib.PulseDomainInterface.PathContext.t -> IBase.Location.t -> Pulselib.PulseDomainInterface.ExecutionDomain.t Pulselib.PulseDomainInterface.AccessResult.t diff --git a/odoc/next/infer/Pulselib/PulseResult/index.html b/odoc/next/infer/Pulselib/PulseResult/index.html index 54819a4634c..df2096070cf 100644 --- a/odoc/next/infer/Pulselib/PulseResult/index.html +++ b/odoc/next/infer/Pulselib/PulseResult/index.html @@ -1,5 +1,10 @@ -PulseResult (infer.Pulselib.PulseResult)

    Module Pulselib.PulseResult

    type ('ok, 'err) t =
    1. | Ok of 'ok
    2. | Recoverable of 'ok * 'err list
    3. | FatalError of 'err * 'err list

    Pulse's base error monad: some errors can be accumulated along paths, others are fatal and there's no point continuing the execution.

    val append_errors : 'err list -> ('ok, 'err) t -> ('ok, 'err) t

    adds the given error list to the result, possibly changing an Ok result into a Recoverable one in the process

    val ok : ('ok, _) t -> 'ok option
    val ok_exn : ('ok, _) t -> 'ok

    dies if the argument is not of the form Ok _

    val map : ('ok, 'err) t -> f:('ok -> 'okk) -> ('okk, 'err) t
    val map_error : ('ok, 'err) t -> f:('err -> 'err') -> ('ok, 'err') t
    val bind : ('ok, 'err) t -> f:('ok -> ('okk, 'err) t) -> ('okk, 'err) t
    val join : (('ok, 'err) t, 'err) t -> ('ok, 'err) t

    Interaction with other datatypes

    val of_some : ('ok option, 'err) t -> ('ok, 'err) t option
    val recoverable_of_result : +PulseResult (infer.Pulselib.PulseResult)

    Module Pulselib.PulseResult

    module F = Stdlib.Format
    type ('ok, 'err) t =
    1. | Ok of 'ok
    2. | Recoverable of 'ok * 'err list
    3. | FatalError of 'err * 'err list

    Pulse's base error monad: some errors can be accumulated along paths, others are fatal and there's no point continuing the execution.

    val pp : + (F.formatter -> 'ok -> unit) -> + (F.formatter -> 'err -> unit) -> + F.formatter -> + ('ok, 'err) t -> + unit
    val append_errors : 'err list -> ('ok, 'err) t -> ('ok, 'err) t

    adds the given error list to the result, possibly changing an Ok result into a Recoverable one in the process

    val ok : ('ok, _) t -> 'ok option
    val ok_exn : ('ok, _) t -> 'ok

    dies if the argument is not of the form Ok _

    val map : ('ok, 'err) t -> f:('ok -> 'okk) -> ('okk, 'err) t
    val map_error : ('ok, 'err) t -> f:('err -> 'err') -> ('ok, 'err') t
    val bind : ('ok, 'err) t -> f:('ok -> ('okk, 'err) t) -> ('okk, 'err) t
    val join : (('ok, 'err) t, 'err) t -> ('ok, 'err) t

    Interaction with other datatypes

    val of_some : ('ok option, 'err) t -> ('ok, 'err) t option
    val recoverable_of_result : ok_of_error:('err -> 'ok) -> ('ok, 'err) IStdlib.IStd.result -> ('ok, 'err) t

    changes Result.Error to Recoverable using ok_of_error

    val fatal_of_result : ('ok, 'err) IStdlib.IStd.result -> ('ok, 'err) t

    changes Result.Error to FatalError

    val to_result : ('ok, 'err) t -> ('ok, 'err list) IStdlib.IStd.result

    Recoverable and FatalError are both sent to Error

    val list_fold : diff --git a/odoc/next/infer/Pulselib/PulseSummary/index.html b/odoc/next/infer/Pulselib/PulseSummary/index.html index 0e4702392c9..ab6c4434099 100644 --- a/odoc/next/infer/Pulselib/PulseSummary/index.html +++ b/odoc/next/infer/Pulselib/PulseSummary/index.html @@ -5,13 +5,16 @@ t Absint.InterproceduralAnalysis.t -> IR.Specialization.Pulse.t option -> IBase.Location.t -> - Pulselib.PulseDomainInterface.ExecutionDomain.t list -> + (Pulselib.PulseDomainInterface.ExecutionDomain.t + * Pulselib.PulseDomainInterface.PathContext.t) + list -> Pulselib.PulseDomainInterface.NonDisjDomain.t -> summary
    val empty : summary
    val join : summary -> summary -> summary
    val force_exit_program : t Absint.InterproceduralAnalysis.t -> + Pulselib.PulseDomainInterface.PathContext.t -> IBase.Location.t -> Pulselib.PulseDomainInterface.ExecutionDomain.t -> _ Pulselib.PulseDomainInterface.ExecutionDomain.base_t diff --git a/odoc/next/infer/Pulselib/PulseTaintConfig/SinkPolicy/index.html b/odoc/next/infer/Pulselib/PulseTaintConfig/SinkPolicy/index.html index eab1429c813..6a5d03a8f53 100644 --- a/odoc/next/infer/Pulselib/PulseTaintConfig/SinkPolicy/index.html +++ b/odoc/next/infer/Pulselib/PulseTaintConfig/SinkPolicy/index.html @@ -1,2 +1,2 @@ -SinkPolicy (infer.Pulselib.PulseTaintConfig.SinkPolicy)

    Module PulseTaintConfig.SinkPolicy

    type t = {
    1. source_kinds : Kind.t list;
    2. sanitizer_kinds : Kind.t list;
    3. description : string;
    4. policy_id : int;
    5. privacy_effect : string option;
    6. exclude_in : string list option;
    7. exclude_matching : IStdlib.IStd.Str.regexp list option;
    8. report_as_issue_type : string option;
    9. report_as_category : string option;
    }
    include Ppx_compare_lib.Equal.S with type t := t
    val equal : t Base__Ppx_compare_lib.equal
    val sink_policies : (Kind.t, t list) Base.Hashtbl.t
    +SinkPolicy (infer.Pulselib.PulseTaintConfig.SinkPolicy)

    Module PulseTaintConfig.SinkPolicy

    type t = {
    1. source_kinds : Kind.t list;
    2. sanitizer_kinds : Kind.t list;
    3. description : string;
    4. policy_id : int;
    5. privacy_effect : string option;
    6. exclude_in : string list option;
    7. exclude_matching : Str.regexp list option;
    8. report_as_issue_type : string option;
    9. report_as_category : string option;
    }
    include Ppx_compare_lib.Equal.S with type t := t
    val equal : t Base__Ppx_compare_lib.equal
    val sink_policies : (Kind.t, t list) Base.Hashtbl.t
    diff --git a/odoc/next/infer/Pulselib/PulseTaintConfig/Unit/index.html b/odoc/next/infer/Pulselib/PulseTaintConfig/Unit/index.html index 360b1a4dd14..16727ba912f 100644 --- a/odoc/next/infer/Pulselib/PulseTaintConfig/Unit/index.html +++ b/odoc/next/infer/Pulselib/PulseTaintConfig/Unit/index.html @@ -1,2 +1,2 @@ -Unit (infer.Pulselib.PulseTaintConfig.Unit)

    Module PulseTaintConfig.Unit

    type procedure_matcher =
    1. | ProcedureName of {
      1. name : string;
      }
    2. | ProcedureNameRegex of {
      1. name_regex : IStdlib.IStd.Str.regexp;
      2. exclude_in : string list option;
      3. exclude_names : string list option;
      }
    3. | ClassNameRegex of {
      1. name_regex : IStdlib.IStd.Str.regexp;
      2. exclude_in : string list option;
      3. exclude_names : string list option;
      }
    4. | ClassAndMethodNames of {
      1. class_names : string list;
      2. method_names : string list;
      }
    5. | ClassNameAndMethodRegex of {
      1. class_names : string list;
      2. method_name_regex : IStdlib.IStd.Str.regexp;
      3. exclude_in : string list option;
      4. exclude_names : string list option;
      }
    6. | ClassRegexAndMethodRegex of {
      1. class_name_regex : IStdlib.IStd.Str.regexp;
      2. method_name_regex : IStdlib.IStd.Str.regexp;
      3. exclude_in : string list option;
      4. exclude_names : string list option;
      }
    7. | ClassAndMethodReturnTypeNames of {
      1. class_names : string list;
      2. method_return_type_names : string list;
      }
    8. | ClassRegexAndMethodReturnTypeNames of {
      1. class_name_regex : IStdlib.IStd.Str.regexp;
      2. method_return_type_names : string list;
      3. exclude_in : string list option;
      4. exclude_names : string list option;
      }
    9. | ClassWithAnnotation of {
      1. annotation : string;
      2. annotation_values : string list option;
      }
    10. | ClassWithAnnotationAndRegexAndMethodRegex of {
      1. annotation : string;
      2. annotation_values : string list option;
      3. class_name_regex : IStdlib.IStd.Str.regexp;
      4. method_name_regex : IStdlib.IStd.Str.regexp;
      5. exclude_in : string list option;
      6. exclude_names : string list option;
      }
    11. | OverridesOfClassWithAnnotation of {
      1. annotation : string;
      }
    12. | MethodWithAnnotation of {
      1. annotation : string;
      2. annotation_values : string list option;
      }
    13. | Block of {
      1. name : string;
      }
    14. | BlockNameRegex of {
      1. name_regex : IStdlib.IStd.Str.regexp;
      2. exclude_in : string list option;
      }
    15. | Allocation of {
      1. class_name : string;
      }
    type field_matcher =
    1. | FieldRegex of {
      1. name_regex : IStdlib.IStd.Str.regexp;
      2. exclude_in : string list option;
      3. exclude_names : string list option;
      }
    2. | ClassAndFieldNames of {
      1. class_names : string list;
      2. field_names : string list;
      }
    3. | FieldWithAnnotation of {
      1. annotation : string;
      2. annotation_values : string list option;
      }
    type procedure_unit = {
    1. procedure_matcher : procedure_matcher;
    2. arguments : ATDGenerated.Pulse_config_t.argument_constraint list;
    3. kinds : Kind.t list;
    4. procedure_target : Target.procedure_target;
    }
    type field_unit = {
    1. field_matcher : field_matcher;
    2. kinds : Kind.t list;
    3. field_target : Target.field_target;
    4. sanitized_in : string list option;
    }
    type t =
    1. | ProcedureUnit of procedure_unit
    2. | FieldUnit of field_unit
    +Unit (infer.Pulselib.PulseTaintConfig.Unit)

    Module PulseTaintConfig.Unit

    type procedure_matcher =
    1. | ProcedureName of {
      1. name : string;
      }
    2. | ProcedureNameRegex of {
      1. name_regex : Str.regexp;
      2. exclude_in : string list option;
      3. exclude_names : string list option;
      }
    3. | ClassNameRegex of {
      1. name_regex : Str.regexp;
      2. exclude_in : string list option;
      3. exclude_names : string list option;
      }
    4. | ClassAndMethodNames of {
      1. class_names : string list;
      2. method_names : string list;
      }
    5. | ClassNameAndMethodRegex of {
      1. class_names : string list;
      2. method_name_regex : Str.regexp;
      3. exclude_in : string list option;
      4. exclude_names : string list option;
      }
    6. | ClassRegexAndMethodRegex of {
      1. class_name_regex : Str.regexp;
      2. method_name_regex : Str.regexp;
      3. exclude_in : string list option;
      4. exclude_names : string list option;
      }
    7. | ClassAndMethodReturnTypeNames of {
      1. class_names : string list;
      2. method_return_type_names : string list;
      }
    8. | ClassRegexAndMethodReturnTypeNames of {
      1. class_name_regex : Str.regexp;
      2. method_return_type_names : string list;
      3. exclude_in : string list option;
      4. exclude_names : string list option;
      }
    9. | ClassWithAnnotation of {
      1. annotation : string;
      2. annotation_values : string list option;
      }
    10. | ClassWithAnnotationAndRegexAndMethodRegex of {
      1. annotation : string;
      2. annotation_values : string list option;
      3. class_name_regex : Str.regexp;
      4. method_name_regex : Str.regexp;
      5. exclude_in : string list option;
      6. exclude_names : string list option;
      }
    11. | OverridesOfClassWithAnnotation of {
      1. annotation : string;
      }
    12. | MethodWithAnnotation of {
      1. annotation : string;
      2. annotation_values : string list option;
      }
    13. | Block of {
      1. name : string;
      }
    14. | BlockNameRegex of {
      1. name_regex : Str.regexp;
      2. exclude_in : string list option;
      }
    15. | Allocation of {
      1. class_name : string;
      }
    type field_matcher =
    1. | FieldRegex of {
      1. name_regex : Str.regexp;
      2. exclude_in : string list option;
      3. exclude_names : string list option;
      }
    2. | ClassAndFieldNames of {
      1. class_names : string list;
      2. field_names : string list;
      }
    3. | FieldWithAnnotation of {
      1. annotation : string;
      2. annotation_values : string list option;
      }
    type procedure_unit = {
    1. procedure_matcher : procedure_matcher;
    2. arguments : ATDGenerated.Pulse_config_t.argument_constraint list;
    3. kinds : Kind.t list;
    4. procedure_target : Target.procedure_target;
    }
    type field_unit = {
    1. field_matcher : field_matcher;
    2. kinds : Kind.t list;
    3. field_target : Target.field_target;
    4. sanitized_in : string list option;
    }
    type t =
    1. | ProcedureUnit of procedure_unit
    2. | FieldUnit of field_unit
    diff --git a/odoc/next/infer/PythonFrontend/PyIR2Textual/index.html b/odoc/next/infer/PythonFrontend/PyIR2Textual/index.html new file mode 100644 index 00000000000..ae7c403e7a5 --- /dev/null +++ b/odoc/next/infer/PythonFrontend/PyIR2Textual/index.html @@ -0,0 +1,4 @@ + +PyIR2Textual (infer.PythonFrontend.PyIR2Textual)

    Module PythonFrontend.PyIR2Textual

    diff --git a/odoc/next/infer/Textuallib/TextualSil/index.html b/odoc/next/infer/Textuallib/TextualSil/index.html index 103d2bdaebd..670a6fb012f 100644 --- a/odoc/next/infer/Textuallib/TextualSil/index.html +++ b/odoc/next/infer/Textuallib/TextualSil/index.html @@ -6,4 +6,4 @@ (IR.Cfg.t * IR.Tenv.t, Textual.transform_error list) IStdlib.IStd.result

    convert a Textual unit into Infer internal representation (cfg + tenv). During the process the textual representation undergoes several transformations. The result is passed as the third element of the returned tuple

    val from_java : filename:string -> IR.Tenv.t -> IR.Cfg.t -> unit

    generate a .sil file with name filename containing all the functions in the given cfg

    val dump_module : filename:string -> Textual.Module.t -> unit

    generate a .sil file with name filename with all the content of the input module

    val default_return_type : Textual.Lang.t option -> Textual.Location.t -> - Textual.Typ.t
    val hack_dict_type_name : IR.Typ.name
    val hack_dict_iter_type_name : IR.Typ.name
    val hack_vec_type_name : IR.Typ.name
    val hack_vec_iter_type_name : IR.Typ.name
    val hack_bool_type_name : IR.Typ.name
    val hack_int_type_name : IR.Typ.name
    val hack_float_type_name : IR.Typ.name
    val hack_string_type_name : IR.Typ.name
    val hack_splated_vec_type_name : IR.Typ.name
    val hack_mixed_type_name : IR.Typ.name
    val hack_awaitable_type_name : IR.Typ.name
    val hack_mixed_static_companion_type_name : IR.Typ.name
    val hack_builtins_type_name : IR.Typ.name
    val hack_root_type_name : IR.Typ.name
    val python_dict_type_name : IR.Typ.name
    val python_int_type_name : IR.Typ.name
    val python_none_type_name : IR.Typ.name
    val python_mixed_type_name : IR.Typ.name
    val python_tuple_type_name : IR.Typ.name
    val python_unresolved_module_type_name : IR.Typ.name
    val python_resolved_module_type_name : IR.Typ.name
    val wildcard_sil_fieldname : Textual.Lang.t -> string -> IR.Fieldname.t
    val textual_ext : string
    val to_filename : string -> string
    + Textual.Typ.t
    val hack_dict_type_name : IR.Typ.name
    val hack_dict_iter_type_name : IR.Typ.name
    val hack_vec_type_name : IR.Typ.name
    val hack_vec_iter_type_name : IR.Typ.name
    val hack_bool_type_name : IR.Typ.name
    val hack_int_type_name : IR.Typ.name
    val hack_float_type_name : IR.Typ.name
    val hack_string_type_name : IR.Typ.name
    val hack_splated_vec_type_name : IR.Typ.name
    val hack_mixed_type_name : IR.Typ.name
    val hack_awaitable_type_name : IR.Typ.name
    val hack_mixed_static_companion_type_name : IR.Typ.name
    val hack_builtins_type_name : IR.Typ.name
    val hack_root_type_name : IR.Typ.name
    val python_dict_type_name : IR.Typ.name
    val python_int_type_name : IR.Typ.name
    val python_none_type_name : IR.Typ.name
    val python_mixed_type_name : IR.Typ.name
    val python_tuple_type_name : IR.Typ.name
    val wildcard_sil_fieldname : Textual.Lang.t -> string -> IR.Fieldname.t
    val textual_ext : string
    val to_filename : string -> string
    diff --git a/odoc/next/infer/Textuallib/TextualVerification/index.html b/odoc/next/infer/Textuallib/TextualVerification/index.html new file mode 100644 index 00000000000..2618b8dac06 --- /dev/null +++ b/odoc/next/infer/Textuallib/TextualVerification/index.html @@ -0,0 +1,8 @@ + +TextualVerification (infer.Textuallib.TextualVerification)

    Module Textuallib.TextualVerification

    type error
    val pp_error : Stdlib.Format.formatter -> error -> unit
    val pp_error_with_sourcefile : + Textual.SourceFile.t -> + Stdlib.Format.formatter -> + error -> + unit

    perform verification (some basic rules, simple type checking, no duplicate declaration) and returns a new version (after type inference)

    diff --git a/search/index.html b/search/index.html index 6672ffaf92e..da3c7f48b0d 100644 --- a/search/index.html +++ b/search/index.html @@ -13,7 +13,7 @@ - +