diff --git a/website/checkers.json b/website/checkers.json
index 05397cedaf0..b8551dcca15 100644
--- a/website/checkers.json
+++ b/website/checkers.json
@@ -4,7 +4,8 @@
"all-checkers", "all-categories", "all-issue-types",
"checker-annotation-reachability", "checker-biabduction",
"checker-bufferoverrun", "checker-config-impact-analysis",
- "checker-cost", "checker-fragment-retains-view", "checker-impurity",
+ "checker-cost", "checker-dispatch-once-static-init",
+ "checker-fragment-retains-view", "checker-impurity",
"checker-inefficient-keyset-iterator", "checker-lineage",
"checker-litho-required-props", "checker-liveness",
"checker-loop-hoisting", "checker-parameter-not-null-checked",
diff --git a/website/docs/all-categories.md b/website/docs/all-categories.md
index 7026943eab1..440534cca62 100644
--- a/website/docs/all-categories.md
+++ b/website/docs/all-categories.md
@@ -10,6 +10,7 @@ Concurrent accesses to the same resource conflict in a way that can give incorre
Issue types in this category:
- [DEADLOCK](/docs/next/all-issue-types#deadlock)
+- [DISPATCH_ONCE_IN_STATIC_INIT](/docs/next/all-issue-types#dispatch_once_in_static_init)
- [GUARDEDBY_VIOLATION](/docs/next/all-issue-types#guardedby_violation)
- [INTERFACE_NOT_THREAD_SAFE](/docs/next/all-issue-types#interface_not_thread_safe)
- [LOCK_CONSISTENCY_VIOLATION](/docs/next/all-issue-types#lock_consistency_violation)
@@ -32,6 +33,7 @@ Issue types in this category:
- [CXX_STRING_CAPTURED_IN_BLOCK](/docs/next/all-issue-types#cxx_string_captured_in_block)
- [NIL_MESSAGING_TO_NON_POD](/docs/next/all-issue-types#nil_messaging_to_non_pod)
- [NIL_MESSAGING_TO_NON_POD_LATENT](/docs/next/all-issue-types#nil_messaging_to_non_pod_latent)
+- [NSSTRING_INTERNAL_PTR_CAPTURED_IN_BLOCK](/docs/next/all-issue-types#nsstring_internal_ptr_captured_in_block)
- [PULSE_REFERENCE_STABILITY](/docs/next/all-issue-types#pulse_reference_stability)
- [PULSE_UNINITIALIZED_VALUE](/docs/next/all-issue-types#pulse_uninitialized_value)
- [STACK_VARIABLE_ADDRESS_ESCAPE](/docs/next/all-issue-types#stack_variable_address_escape)
diff --git a/website/docs/all-checkers.md b/website/docs/all-checkers.md
index f38ee777954..6895e942795 100644
--- a/website/docs/all-checkers.md
+++ b/website/docs/all-checkers.md
@@ -7,7 +7,7 @@ Here is an overview of the checkers currently available in Infer.
## Annotation Reachability
-Given pairs of source and sink annotations, e.g. `@A` and `@B`, this checker will warn whenever some method annotated with `@A` calls, directly or indirectly, another method annotated with `@B`. Besides the custom pairs, it is also possible to enable some built-in checks, such as `@PerformanceCritical` reaching `@Expensive` or `@NoAllocation` reaching `new`. See flags starting with `--annotation-reachability`.
+Given pairs of source and sink annotations, e.g. `@A` and `@B`, this checker will warn whenever some method annotated with `@A` calls, directly or indirectly, another method annotated with `@B`. Besides the custom pairs, it is also possible to enable some built-in checks, such as `@PerformanceCritical` reaching `@Expensive` or `@NoAllocation` reaching `new`. It is also possible to model methods as if they were annotated, using regular expressions. This should also work in languages where there are no annotations. See flags starting with `--annotation-reachability`.
[Visit here for more information.](/docs/next/checker-annotation-reachability)
@@ -37,6 +37,12 @@ Computes the asymptotic complexity of functions with respect to execution cost o
[Visit here for more information.](/docs/next/checker-cost)
+## dispatch-once in static init
+
+Detect if dispatch_once is called from a static constructor.
+
+[Visit here for more information.](/docs/next/checker-dispatch-once-static-init)
+
## Fragment Retains View
Detects when Android fragments are not explicitly nullified before becoming unreachable.
diff --git a/website/docs/all-issue-types.md b/website/docs/all-issue-types.md
index 4c085d6a8cb..b43c1948cee 100644
--- a/website/docs/all-issue-types.md
+++ b/website/docs/all-issue-types.md
@@ -554,25 +554,21 @@ dereferences it later.
*Category: [Memory error](/docs/next/all-categories#memory-error). Reported as "C++ String Captured in Block" by [self-in-block](/docs/next/checker-self-in-block).*
-This check flags when a local variable of type `std::string` is captured in an escaping block.
+This check flags when an internal pointer of a local variable of type `std::string` is captured in an escaping block.
This means that the block will be leaving the current scope, i.e. it is
not annotated with `__attribute__((noescape))`.
Example:
```
-- (void)string_captured_in_escaping_block_bad {
std::string fullName;
+ const char* c = fullName.c_str();
dispatch_async(dispatch_get_main_queue(), ^{
- const char* c = fullName.c_str();
- ...
+ const char* c1 = c;
});
- ...;
-}
```
-This could cause crashes because the variable is likely to be freed if the block
-uses it later.
+This could cause crashes because the variable is likely to be freed when the code is executed, leaving the pointer dangling.
## DANGLING_POINTER_DEREFERENCE
@@ -656,6 +652,11 @@ To suppress reports of deadlocks in a method `m()` use the
This error is reported in C++. It fires when the value assigned to a variables
is never used (e.g., `int i = 1; i = 2; return i;`).
+## DISPATCH_ONCE_IN_STATIC_INIT
+
+*Category: [Concurrency](/docs/next/all-categories#concurrency). Reported as "dispatch_once in static init" by [dispatch-once-static-init](/docs/next/checker-dispatch-once-static-init).*
+
+Calling dispatch_once during the static initialization of objects is risky, for example it could cause deadlocks, because other objects might not have been initialized yet.
## DIVIDE_BY_ZERO
*Reported as "Divide By Zero" by [biabduction](/docs/next/checker-biabduction).*
@@ -1494,6 +1495,26 @@ sign(X) ->
*Category: [Runtime exception](/docs/next/all-categories#runtime-exception). Reported as "No True Branch In If Latent" by [pulse](/docs/next/checker-pulse).*
A latent [NO_TRUE_BRANCH_IN_IF](#no_true_branch_in_if). See the [documentation on Pulse latent issues](/docs/next/checker-pulse#latent-issues).
+## NSSTRING_INTERNAL_PTR_CAPTURED_IN_BLOCK
+
+*Category: [Memory error](/docs/next/all-categories#memory-error). Reported as "NSString Captured in Block" by [self-in-block](/docs/next/checker-self-in-block).*
+
+This check flags when an internal pointer of a local variable of type `std::string` is captured in an escaping block.
+This means that the block will be leaving the current scope, i.e. it is
+not annotated with `__attribute__((noescape))`.
+
+Example:
+
+```
+ std::string fullName;
+ const char* c = fullName.c_str();
+ dispatch_async(dispatch_get_main_queue(), ^{
+ const char* c1 = c;
+ });
+```
+
+This could cause crashes because the variable is likely to be freed when the code is executed, leaving the pointer dangling.
+
## NULLPTR_DEREFERENCE
*Category: [Null pointer dereference](/docs/next/all-categories#null-pointer-dereference). Reported as "Null Dereference" by [pulse](/docs/next/checker-pulse).*
@@ -2013,7 +2034,41 @@ Failure to `await` an `Awaitable` can lead to non-deterministic amount of the as
*Category: [Resource leak](/docs/next/all-categories#resource-leak). Reported as "Unfinished Builder" by [pulse](/docs/next/checker-pulse).*
-See [RESOURCE_LEAK](#resource_leak)
+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.
+
+```hack
+class MyBuilder {
+ private int $a = 0;
+ private int $b = 0;
+
+ public function setA(int $a): MyBuilder {
+ $this->a = $a;
+ return $this;
+ }
+
+ public function setB(int $b): MyBuilder {
+ $this->b = $b;
+ return $this;
+ }
+
+ public function saveX(): AwaitableOPTIONS
Besides the custom pairs, it is also possible to enable some
built-in checks, such as ‘@PerformanceCritical‘
reaching ‘@Expensive‘ or
-‘@NoAllocation‘ reaching ‘new‘. See
-flags starting with ‘--annotation-reachability‘.
-(Conversely: --no-annotation-reachability)
--annotation-reachability-only
@@ -232,6 +235,7 @@--no-default-checkers
Deactivates: Default checkers: +--dispatch-once-static-init, --fragment-retains-view, --inefficient-keyset-iterator, --liveness, --parameter-not-null-checked, --pulse, @@ -258,6 +262,22 @@
--no-dispatch-once-static-init
+ +Deactivates: +dispatch-once-static-init checker: Detect if +dispatch_once is called from a static constructor. +(Conversely: --dispatch-once-static-init)
+ + +--dispatch-once-static-init-only
+ +Activates: Enable +dispatch-once-static-init and disable all other +checkers (Conversely: +--no-dispatch-once-static-init-only)
+ +--files-to-analyze-index file
@@ -488,6 +508,21 @@--ondemand-recursion-restart-limit +int
+ +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 +deterministic place. If the graph of mutual recursion is +more complex than a simple cycle this could potentially +result in many restarts before finding the "right" +procedure from which to start. This limits the number of +restarts before we give up and analyze the cycle as-is +instead.
+ +--no-parameter-not-null-checked
Deactivates: @@ -1417,6 +1452,13 @@
--pulse-model-unknown-pure ++string
+ +Regex of methods that should be +modelled as unknown pure in Pulse
+ +--pulse-models-for-erlang +path
@@ -1482,6 +1524,14 @@--pulse-over-approximate-reasoning
+ +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 int
@@ -1747,6 +1797,19 @@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)
See also
infer-analyze(1).
@@ -861,6 +864,7 @@ OPTIONS
--no-default-checkers
Deactivates: Default checkers: +--dispatch-once-static-init, --fragment-retains-view, --inefficient-keyset-iterator, --liveness, --parameter-not-null-checked, --pulse, @@ -978,6 +982,7 @@
Deactivates: +dispatch-once-static-init checker: Detect if +dispatch_once is called from a static constructor. +(Conversely: --dispatch-once-static-init)
+ +See also
+infer-analyze(1).
+--dispatch-once-static-init-only
Activates: Enable +dispatch-once-static-init and disable all other +checkers (Conversely: +--no-dispatch-once-static-init-only)
+ +See also
+infer-analyze(1).
--dump-duplicate-symbols
Activates: Dump all symbols @@ -1970,6 +1995,21 @@
See also
infer-capture(1).
+--ondemand-recursion-restart-limit int
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 +deterministic place. If the graph of mutual recursion is +more complex than a simple cycle this could potentially +result in many restarts before finding the "right" +procedure from which to start. This limits the number of +restarts before we give up and analyze the cycle as-is +instead.
+ +See also
+infer-analyze(1).
--no-parameter-not-null-checked
Deactivates: @@ -2360,6 +2400,13 @@
See also
+infer-analyze(1).
+--pulse-model-unknown-pure +string
Regex of methods that should be +modelled as unknown pure in Pulse
+See also
infer-analyze(1).
--pulse-model-unreachable +string
See also
+infer-analyze(1).
+--pulse-over-approximate-reasoning
Activates: [EXPERIMENTAL] add +over-approximate reasoning on top of the under-approximate, +disjunctive reasoning of Pulse. (Conversely: +--no-pulse-over-approximate-reasoning)
+See also
infer-analyze(1).
--pulse-recency-limit int
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 diff --git a/website/static/odoc/next/infer/Absint/AbstractDomain/BottomLiftedUtils/index.html b/website/static/odoc/next/infer/Absint/AbstractDomain/BottomLiftedUtils/index.html index 122be83fb71..bd2ed7de337 100644 --- a/website/static/odoc/next/infer/Absint/AbstractDomain/BottomLiftedUtils/index.html +++ b/website/static/odoc/next/infer/Absint/AbstractDomain/BottomLiftedUtils/index.html @@ -1,2 +1,6 @@ -
AbstractDomain.BottomLiftedUtils
AbstractDomain.BottomLiftedUtils
val pp :
+ (F.formatter -> 't -> unit) ->
+ F.formatter ->
+ 't Types.bottom_lifted ->
+ unit
FiniteMultiMap.Key
include IStdlib.PrettyPrintable.PrintableType with type t := t
val pp : IStdlib.PrettyPrintable.F.formatter -> t -> unit
FiniteMultiMap.Key
include IStdlib.PrettyPrintable.PrintableType with type t := t
val pp : IStdlib.PrettyPrintable.F.formatter -> t -> unit
FiniteMultiMap.Value
include IStdlib.PrettyPrintable.PrintableType with type t := t
val pp : IStdlib.PrettyPrintable.F.formatter -> t -> unit
FiniteMultiMap.Value
include IStdlib.PrettyPrintable.PrintableType with type t := t
val pp : IStdlib.PrettyPrintable.F.formatter -> t -> unit
FiniteSet.Element
include IStdlib.PrettyPrintable.PrintableType with type t := t
val pp : IStdlib.PrettyPrintable.F.formatter -> t -> unit
FiniteSet.Element
include IStdlib.PrettyPrintable.PrintableType with type t := t
val pp : IStdlib.PrettyPrintable.F.formatter -> t -> unit
AbstractDomain.FiniteSet
Lift a set to a powerset domain ordered by subset. The elements of the set should be drawn from a *finite* collection of possible values, since the widening operator here is just union.
include IStdlib.PrettyPrintable.PPSet with type elt = Element.t
val is_singleton_or_more : t -> elt IStdlib.IContainer.singleton_or_more
include IStdlib.PrettyPrintable.PrintableType with type t := t
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 bottom : t
The bottom value of the domain.
val is_bottom : t -> bool
Return true if this is the bottom value
AbstractDomain.FiniteSet
Lift a set to a powerset domain ordered by subset. The elements of the set should be drawn from a *finite* collection of possible values, since the widening operator here is just union.
include IStdlib.PrettyPrintable.PPSet with type elt = Element.t
val is_singleton_or_more : t -> elt IStdlib.IContainer.singleton_or_more
include IStdlib.PrettyPrintable.PrintableType with type t := t
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 bottom : t
The bottom value of the domain.
val is_bottom : t -> bool
Return true if this is the bottom value
FiniteSetOfPPSet.PPSet
val is_singleton_or_more : t -> elt IStdlib.IContainer.singleton_or_more
include IStdlib.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
FiniteSetOfPPSet.PPSet
val is_singleton_or_more : t -> elt IStdlib.IContainer.singleton_or_more
include IStdlib.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
AbstractDomain.FiniteSetOfPPSet
Lift a PPSet to a powerset domain ordered by subset. The elements of the set should be drawn from a *finite* collection of possible values, since the widening operator here is just union.
module PPSet : IStdlib.PrettyPrintable.PPSet
include IStdlib.PrettyPrintable.PPSet
with type t = PPSet.t
- with type elt = PPSet.elt
val is_singleton_or_more : t -> elt IStdlib.IContainer.singleton_or_more
include IStdlib.PrettyPrintable.PrintableType with type t := t
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 bottom : t
The bottom value of the domain.
val is_bottom : t -> bool
Return true if this is the bottom value
val is_singleton_or_more : t -> elt IStdlib.IContainer.singleton_or_more
include IStdlib.PrettyPrintable.PrintableType with type t := t
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 bottom : t
The bottom value of the domain.
val is_bottom : t -> bool
Return true if this is the bottom value