From f9b6f2bdf1abadebef9767294f7ffd93d514fa1f Mon Sep 17 00:00:00 2001
From: Jules Villard
Date: Thu, 25 Mar 2021 08:13:11 -0700
Subject: [PATCH] [Topl] add doc and change TOPL -> Topl
Summary:
Copied the documentation from a document created by rgrig
(thanks!!).
Reviewed By: rgrig
Differential Revision: D27325829
fbshipit-source-id: 118e1a2be
---
infer/documentation/checkers/Topl.md | 97 +++++++++++++++++
infer/man/man1/infer-analyze.txt | 6 +-
infer/man/man1/infer-full.txt | 8 +-
infer/man/man1/infer.txt | 6 +-
infer/src/backend/dune | 4 +-
infer/src/base/Checker.ml | 10 +-
infer/src/base/Checker.mli | 2 +-
infer/src/base/Config.ml | 2 +-
infer/src/base/IssueType.ml | 5 +-
infer/src/dune.in | 2 +-
infer/src/pulse/PulseAbductiveDomain.ml | 2 +-
infer/src/pulse/PulseTopl.ml | 6 +-
infer/src/pulse/dune | 4 +-
infer/src/topl/Topl.ml | 2 +-
infer/src/topl/ToplAutomaton.mli | 2 +-
infer/src/topl/dune | 4 +-
scripts/toplevel_init | 2 +-
website/docs/all-issue-types.md | 2 +-
website/docs/checker-topl.md | 103 +++++++++++++++++-
website/static/man/next/infer-analyze.1.html | 6 +-
website/static/man/next/infer.1.html | 6 +-
.../odoc/next/infer/IBase/Checker/index.html | 2 +-
.../odoc/next/infer/IBase__Checker/index.html | 2 +-
.../odoc/next/infer/IR/Procdesc/index.html | 2 +-
.../odoc/next/infer/IR__Procdesc/index.html | 2 +-
.../infer/{TOPLlib => Topllib}/.dune-keep | 0
.../{TOPLlib => Topllib}/Topl/index.html | 2 +-
.../{TOPLlib => Topllib}/ToplAst/index.html | 2 +-
.../ToplAstOps/index.html | 2 +-
.../ToplAutomaton/index.html | 2 +-
.../{TOPLlib => Topllib}/ToplLexer/index.html | 2 +-
.../ToplParser/index.html | 2 +-
.../infer/{TOPLlib => Topllib}/index.html | 2 +-
.../.dune-keep | 0
.../index.html | 2 +-
.../.dune-keep | 0
.../index.html | 2 +-
.../.dune-keep | 0
.../index.html | 2 +-
.../.dune-keep | 0
.../index.html | 2 +-
.../.dune-keep | 0
.../index.html | 2 +-
.../.dune-keep | 0
.../index.html | 2 +-
website/static/odoc/next/infer/index.html | 2 +-
46 files changed, 258 insertions(+), 59 deletions(-)
create mode 100644 infer/documentation/checkers/Topl.md
rename website/static/odoc/next/infer/{TOPLlib => Topllib}/.dune-keep (100%)
rename website/static/odoc/next/infer/{TOPLlib => Topllib}/Topl/index.html (84%)
rename website/static/odoc/next/infer/{TOPLlib => Topllib}/ToplAst/index.html (98%)
rename website/static/odoc/next/infer/{TOPLlib => Topllib}/ToplAstOps/index.html (80%)
rename website/static/odoc/next/infer/{TOPLlib => Topllib}/ToplAutomaton/index.html (96%)
rename website/static/odoc/next/infer/{TOPLlib => Topllib}/ToplLexer/index.html (93%)
rename website/static/odoc/next/infer/{TOPLlib => Topllib}/ToplParser/index.html (97%)
rename website/static/odoc/next/infer/{TOPLlib => Topllib}/index.html (88%)
rename website/static/odoc/next/infer/{TOPLlib__Topl => Topllib__Topl}/.dune-keep (100%)
rename website/static/odoc/next/infer/{TOPLlib__Topl => Topllib__Topl}/index.html (67%)
rename website/static/odoc/next/infer/{TOPLlib__ToplAst => Topllib__ToplAst}/.dune-keep (100%)
rename website/static/odoc/next/infer/{TOPLlib__ToplAst => Topllib__ToplAst}/index.html (98%)
rename website/static/odoc/next/infer/{TOPLlib__ToplAstOps => Topllib__ToplAstOps}/.dune-keep (100%)
rename website/static/odoc/next/infer/{TOPLlib__ToplAstOps => Topllib__ToplAstOps}/index.html (66%)
rename website/static/odoc/next/infer/{TOPLlib__ToplAutomaton => Topllib__ToplAutomaton}/.dune-keep (100%)
rename website/static/odoc/next/infer/{TOPLlib__ToplAutomaton => Topllib__ToplAutomaton}/index.html (89%)
rename website/static/odoc/next/infer/{TOPLlib__ToplLexer => Topllib__ToplLexer}/.dune-keep (100%)
rename website/static/odoc/next/infer/{TOPLlib__ToplLexer => Topllib__ToplLexer}/index.html (77%)
rename website/static/odoc/next/infer/{TOPLlib__ToplParser => Topllib__ToplParser}/.dune-keep (100%)
rename website/static/odoc/next/infer/{TOPLlib__ToplParser => Topllib__ToplParser}/index.html (95%)
diff --git a/infer/documentation/checkers/Topl.md b/infer/documentation/checkers/Topl.md
new file mode 100644
index 00000000000..1d4223fcfdb
--- /dev/null
+++ b/infer/documentation/checkers/Topl.md
@@ -0,0 +1,97 @@
+# Topl
+
+## What is it?
+
+Topl is an analysis framework, built on top of Infer, for statically finding violations of temporal properties. Many analyses can be encoded as temporal properties supported by Topl, such as taint analysis. As a simple example, suppose that we don't want a value returned by method `source()` to be sent as an argument to a method `sink()`. This can be specified as follows:
+
+```
+property Taint
+ prefix "Main"
+ start -> start: *
+ start -> tracking: source(Ret) => x := Ret
+ tracking -> error: sink(Arg, VoidRet) when x == Arg
+```
+
+This specifies an automaton called `Taint` that has three states (`start`, `tracking`, `error`). Two of those states (`start` and `error`) have special meaning; other states (`tracking`) can have any names. The first transition (`start → tracking`) is taken when a method called `source()` is called, and its return value is stored in a register called `x`; the second transition (`tracking → error`) is taken when a method called `sink()` is called, but only if its argument equals what was previously saved in register `x`.
+This property is violated in the following Java code:
+
+```
+public class Main {
+ static void f() { g(tito(source())); }
+ static void g(Object x) { h(x); }
+ static void h(Object x) { sink(x); }
+ static Object tito(Object x) { return x; }
+ static Object source() { return "dirty"; }
+ static void sink(Object x) {}
+}
+```
+
+Note that `source()` and `sink()` are not called from the same method, and that the “dirty” object is passed around a few times before finally reaching the sink. Assuming that the property is in a file `taint.topl` and the Java code in a file `Main.java`, you can invoke Infer with the following command:
+
+```
+infer --topl --topl-properties taint.topl -- javac Main.java
+```
+
+It will display the following error:
+
+```
+Main.java:2: error: Topl Error
+ property Taint reaches state error.
+ 1. public class Main {
+ 2. > static void f() { g(tito(source())); }
+ 3. static void g(Object x) { h(x); }
+ 4. static void h(Object x) { sink(x); }
+```
+
+To get a full trace, use the command
+
+```
+infer explore
+```
+
+## Specifying Properties
+
+A property is a nondeterministic automaton that can remember values in registers. An execution that drives the automaton from the start state to the error state will make Infer report an issue, and the trace that it produces will indicate which parts of the program drive which transitions of the automaton.
+
+The general form of a property is the following:
+
+```
+property *Name
+* message "Optional error message" // This line can be missing
+ prefix "Prefix" // There can be zero, one, or more prefix declarations
+ sourceState -> targetState: *Pattern*(Arg1,...,ArgN,Ret) when *Condition* => *Action*
+```
+
+The property name and the optional error message are used for reporting issues. The prefix declarations are used to simplify Patterns. The core of the property is the list of transitions.
+
+Each transition has a source state and a target state. The special transition label * means that the transition is always taken. Typically, there is a transition
+
+```
+ start -> start: *
+```
+
+meaning that the property can start anywhere, not just at the beginning of a method.
+
+Otherwise, the label on a transition contains:
+
+* a *Pattern*, which indicates what kind of instruction in the program drives this transition;
+* a list of transition variable bindings (above named Arg1, ..., but any identifier starting with uppercase letters works);
+* possibly a boolean Condition, which can refer to transition variables and to registers;
+* possibly and Action, which is a list sequence of assignments of the form *register* := *TransitionVariable* (registers do not need to be declared, and any identifier starting with a lowercase letter works).
+
+There are two types of patterns:
+
+* a regex that matches method names
+ * if the regex uses non-letters (such as dots) it must be within double-quotes; otherwise, double quotes are optional
+ * the prefix declarations are used to add potential prefixes to the regex. The combine regex is essentially “(prefix_regex_a | prefix_regex_b) transition_pattern_regex“
+ * for a method with n arguments, there must be n+1 transition variables to get a match. The first n transition variables get bound to the argument values, and the last transition variable gets bound to the return value. *This is true even for the case in which the return type is void*.
+* the special keyword **#ArrayWrite**. In that case, there should be two transition variables like “(Array, Index)” — Array gets bound to the array object, and Index gets bound to the index at which the write happens.
+
+For several examples, see https://github.com/facebook/infer/tree/master/infer/tests/codetoanalyze/java/topl
+
+## Limitations
+
+* By design, some problems may be missed. Topl is built on Pulse, which attempts to minimize false positives, at the cost of sometimes having false negatives.
+* Analysis time increases exponentially with the number of registers used in properties.
+ * In theory, there should be no significant slowdown if registers belong to different properties, but the implementation is not yet optimized.
+ * If there are many registers within the same property, then the slowdown is unavoidable (without some significant breakthrough). However, the maximum number of registers we ever used for one practical property was 3.
diff --git a/infer/man/man1/infer-analyze.txt b/infer/man/man1/infer-analyze.txt
index 2eb933640b3..ae94c8cd84b 100644
--- a/infer/man/man1/infer-analyze.txt
+++ b/infer/man/man1/infer-analyze.txt
@@ -411,9 +411,9 @@ OPTIONS
(Conversely: --no-starvation-only)
--topl
- Activates: checker topl: Detects errors based on user-provided
- state machines describing multi-object monitors. (Conversely:
- --no-topl)
+ Activates: checker topl: Detect errors based on user-provided
+ state machines describing temporal properties over multiple
+ objects. (Conversely: --no-topl)
--topl-only
Activates: Enable topl and disable all other checkers (Conversely:
diff --git a/infer/man/man1/infer-full.txt b/infer/man/man1/infer-full.txt
index e36b7f5b86d..22ccadece75 100644
--- a/infer/man/man1/infer-full.txt
+++ b/infer/man/man1/infer-full.txt
@@ -1257,9 +1257,9 @@ OPTIONS
@ThreadSafe See also infer-analyze(1).
--topl
- Activates: checker topl: Detects errors based on user-provided
- state machines describing multi-object monitors. (Conversely:
- --no-topl) See also infer-analyze(1).
+ Activates: checker topl: Detect errors based on user-provided
+ state machines describing temporal properties over multiple
+ objects. (Conversely: --no-topl) See also infer-analyze(1).
--topl-only
Activates: Enable topl and disable all other checkers (Conversely:
@@ -2126,7 +2126,7 @@ INTERNAL OPTIONS
scheduler. (Conversely: --no-trace-ondemand)
--trace-topl
- Activates: Detailed tracing information during TOPL analysis
+ Activates: Detailed tracing information during Topl analysis
(Conversely: --no-trace-topl)
--tv-commit commit
diff --git a/infer/man/man1/infer.txt b/infer/man/man1/infer.txt
index 7ae21082202..0c81d300fdf 100644
--- a/infer/man/man1/infer.txt
+++ b/infer/man/man1/infer.txt
@@ -1257,9 +1257,9 @@ OPTIONS
@ThreadSafe See also infer-analyze(1).
--topl
- Activates: checker topl: Detects errors based on user-provided
- state machines describing multi-object monitors. (Conversely:
- --no-topl) See also infer-analyze(1).
+ Activates: checker topl: Detect errors based on user-provided
+ state machines describing temporal properties over multiple
+ objects. (Conversely: --no-topl) See also infer-analyze(1).
--topl-only
Activates: Enable topl and disable all other checkers (Conversely:
diff --git a/infer/src/backend/dune b/infer/src/backend/dune
index d22d2e752f5..9907a6b7b35 100644
--- a/infer/src/backend/dune
+++ b/infer/src/backend/dune
@@ -10,9 +10,9 @@
(:standard -open Core -open IStdlib -open IStd -open OpenSource -open
ATDGenerated -open IBase -open IR -open Absint -open Biabduction -open BO
-open Nullsafe -open Pulselib -open Checkers -open Costlib -open Quandary
- -open TOPLlib -open Concurrency -open Labs -open Dotnet))
+ -open Topllib -open Concurrency -open Labs -open Dotnet))
(libraries core memtrace IStdlib ATDGenerated IBase IR Absint Biabduction
- Nullsafe BO Checkers Costlib Quandary TOPLlib Concurrency Labs Dotnet)
+ Nullsafe BO Checkers Costlib Quandary Topllib Concurrency Labs Dotnet)
(preprocess
(pps ppx_compare ppx_fields_conv ppx_yojson_conv)))
diff --git a/infer/src/base/Checker.ml b/infer/src/base/Checker.ml
index 9aff84f0517..d5b06a30996 100644
--- a/infer/src/base/Checker.ml
+++ b/infer/src/base/Checker.ml
@@ -37,7 +37,7 @@ type t =
| SIOF
| SelfInBlock
| Starvation
- | TOPL
+ | Topl
| Uninit
[@@deriving equal, enumerate]
@@ -409,12 +409,14 @@ let config_unsafe checker =
; cli_flags= Some {deprecated= []; show_in_help= true}
; enabled_by_default= true
; activates= [] }
- | TOPL ->
+ | Topl ->
{ id= "topl"
- ; kind= UserFacing {title= "TOPL"; markdown_body= ""}
+ ; kind=
+ UserFacing {title= "Topl"; markdown_body= [%blob "../../documentation/checkers/Topl.md"]}
; support= supports_clang_and_java_experimental
; short_documentation=
- "Detects errors based on user-provided state machines describing multi-object monitors."
+ "Detect errors based on user-provided state machines describing temporal properties over \
+ multiple objects."
; cli_flags= Some {deprecated= []; show_in_help= true}
; enabled_by_default= false
; activates= [Pulse] }
diff --git a/infer/src/base/Checker.mli b/infer/src/base/Checker.mli
index 1258183f215..c4ece90dd6a 100644
--- a/infer/src/base/Checker.mli
+++ b/infer/src/base/Checker.mli
@@ -36,7 +36,7 @@ type t =
| SIOF
| SelfInBlock
| Starvation
- | TOPL
+ | Topl
| Uninit
[@@deriving equal, enumerate]
diff --git a/infer/src/base/Config.ml b/infer/src/base/Config.ml
index fc458d5f436..f6f9982d2d5 100644
--- a/infer/src/base/Config.ml
+++ b/infer/src/base/Config.ml
@@ -2500,7 +2500,7 @@ and trace_ondemand =
and trace_topl =
- CLOpt.mk_bool ~long:"trace-topl" "Detailed tracing information during TOPL analysis"
+ CLOpt.mk_bool ~long:"trace-topl" "Detailed tracing information during Topl analysis"
and tv_commit =
diff --git a/infer/src/base/IssueType.ml b/infer/src/base/IssueType.ml
index 02fe7007def..a7ef49cb170 100644
--- a/infer/src/base/IssueType.ml
+++ b/infer/src/base/IssueType.ml
@@ -920,7 +920,10 @@ let complexity_increase ~kind ~is_on_ui_thread =
register_cost ~kind ~is_on_ui_thread "%s_COMPLEXITY_INCREASE"
-let topl_error = register ~id:"TOPL_ERROR" Error TOPL ~user_documentation:"Experimental."
+let topl_error =
+ register ~id:"TOPL_ERROR" Error Topl
+ ~user_documentation:"A violation of a Topl property (user-specified)."
+
let uninitialized_value =
register ~id:"UNINITIALIZED_VALUE" Error Uninit
diff --git a/infer/src/dune.in b/infer/src/dune.in
index 014b2c9278d..77912c2cd37 100644
--- a/infer/src/dune.in
+++ b/infer/src/dune.in
@@ -99,7 +99,7 @@ let infertop_stanza =
(modes byte_complete)
(modules Infertop)
(flags (:standard -open Core -open IStdlib -open IStd))
- (libraries %s utop Absint ASTLanguage ATDGenerated Backend IBase Biabduction BO Checkers Concurrency Costlib CStubs IR IStdlib Labs Dotnet Nullsafe Pulselib Quandary Integration TestDeterminators TOPLlib UnitTests)
+ (libraries %s utop Absint ASTLanguage ATDGenerated Backend IBase Biabduction BO Checkers Concurrency Costlib CStubs IR IStdlib Labs Dotnet Nullsafe Pulselib Quandary Integration TestDeterminators Topllib UnitTests)
(link_flags (-linkall -warn-error -31))
(preprocess (pps ppx_compare))
(promote (until-clean) (into ../bin))
diff --git a/infer/src/pulse/PulseAbductiveDomain.ml b/infer/src/pulse/PulseAbductiveDomain.ml
index 4a80da29b89..905cd04cc96 100644
--- a/infer/src/pulse/PulseAbductiveDomain.ml
+++ b/infer/src/pulse/PulseAbductiveDomain.ml
@@ -99,7 +99,7 @@ type t =
[@@deriving compare, equal, yojson_of]
let pp f {post; pre; topl; path_condition; skipped_calls} =
- F.fprintf f "@[%a@;%a@;PRE=[%a]@;skipped_calls=%a@;TOPL=%a@]" PathCondition.pp path_condition
+ F.fprintf f "@[%a@;%a@;PRE=[%a]@;skipped_calls=%a@;Topl=%a@]" PathCondition.pp path_condition
PostDomain.pp post PreDomain.pp pre SkippedCalls.pp skipped_calls PulseTopl.pp_state topl
diff --git a/infer/src/pulse/PulseTopl.ml b/infer/src/pulse/PulseTopl.ml
index 09bbcdacf74..98cd95ff9c7 100644
--- a/infer/src/pulse/PulseTopl.ml
+++ b/infer/src/pulse/PulseTopl.ml
@@ -246,7 +246,7 @@ let get env x =
| Some v ->
v
| None ->
- L.die InternalError "TOPL: Cannot find %s. Should be caught by static checks" x
+ L.die InternalError "Topl: Cannot find %s. Should be caught by static checks" x
let set = List.Assoc.add ~equal:String.equal
@@ -378,7 +378,7 @@ let dummy_tenv = Tenv.create ()
let is_unsat_expensive path_condition pruned =
let _path_condition, unsat, _new_eqs =
- (* Not enabling dynamic type reasoning in TOPL for now *)
+ (* Not enabling dynamic type reasoning in Topl for now *)
PathCondition.is_unsat_expensive dummy_tenv
~get_dynamic_type:(fun _ -> None)
(Constraint.prune_path pruned path_condition)
@@ -614,6 +614,6 @@ let report_errors proc_desc err_log state =
let loc = Procdesc.get_loc proc_desc in
let ltr = make_trace 0 [] q in
let message = Format.asprintf "%a" ToplAutomaton.pp_message_of_state (a, q.post.vertex) in
- Reporting.log_issue proc_desc err_log ~loc ~ltr TOPL IssueType.topl_error message
+ Reporting.log_issue proc_desc err_log ~loc ~ltr Topl IssueType.topl_error message
in
List.iter ~f:report_simple_state state
diff --git a/infer/src/pulse/dune b/infer/src/pulse/dune
index 3f3af65fe3e..1e9e3c9eb29 100644
--- a/infer/src/pulse/dune
+++ b/infer/src/pulse/dune
@@ -8,7 +8,7 @@
(public_name infer.Pulselib)
(flags
(:standard -open Core -open IR -open IStdlib -open IStd -open ATDGenerated
- -open IBase -open Absint -open BO -open TOPLlib -open Nullsafe))
- (libraries core IStdlib ATDGenerated IBase IR Absint BO TOPLlib Nullsafe)
+ -open IBase -open Absint -open BO -open Topllib -open Nullsafe))
+ (libraries core IStdlib ATDGenerated IBase IR Absint BO Topllib Nullsafe)
(preprocess
(pps ppx_yojson_conv ppx_compare ppx_variants_conv)))
diff --git a/infer/src/topl/Topl.ml b/infer/src/topl/Topl.ml
index e2f0cd75dba..8b14b1b4035 100644
--- a/infer/src/topl/Topl.ml
+++ b/infer/src/topl/Topl.ml
@@ -25,4 +25,4 @@ let properties = lazy (List.concat_map ~f:parse Config.topl_properties)
let automaton () = ToplAutomaton.make (Lazy.force properties)
-let is_active () = Config.is_checker_enabled TOPL && not (List.is_empty (Lazy.force properties))
+let is_active () = Config.is_checker_enabled Topl && not (List.is_empty (Lazy.force properties))
diff --git a/infer/src/topl/ToplAutomaton.mli b/infer/src/topl/ToplAutomaton.mli
index 7a601f42d3f..4a8b73bf57d 100644
--- a/infer/src/topl/ToplAutomaton.mli
+++ b/infer/src/topl/ToplAutomaton.mli
@@ -7,7 +7,7 @@
open! IStd
-(* An automaton is a different representation for a set of TOPL properties: states and transitions
+(* An automaton is a different representation for a set of Topl properties: states and transitions
are identified by nonnegative integers; and transitions are grouped by their source. Also, the
meaning of transition labels does not depend on context (e.g., prefixes are now included).
diff --git a/infer/src/topl/dune b/infer/src/topl/dune
index 65d998b1214..0f1ca015ab4 100644
--- a/infer/src/topl/dune
+++ b/infer/src/topl/dune
@@ -10,8 +10,8 @@
(modules ToplParser))
(library
- (name TOPLlib)
- (public_name infer.TOPLlib)
+ (name Topllib)
+ (public_name infer.Topllib)
(flags
(:standard -open Core -open IR -open IStdlib -open IStd -open ATDGenerated
-open IBase -open Absint -open Biabduction))
diff --git a/scripts/toplevel_init b/scripts/toplevel_init
index 0350bbde20c..593b7796305 100644
--- a/scripts/toplevel_init
+++ b/scripts/toplevel_init
@@ -29,7 +29,7 @@ open Pulselib;;
open Checkers;;
open Costlib;;
open Quandary;;
-open TOPLlib;;
+open Topllib;;
open Concurrency;;
open Labs;;
open OpenSource;;
diff --git a/website/docs/all-issue-types.md b/website/docs/all-issue-types.md
index 84e7b3262b7..9939adb1ca5 100644
--- a/website/docs/all-issue-types.md
+++ b/website/docs/all-issue-types.md
@@ -2230,7 +2230,7 @@ These annotations can be found at `com.facebook.infer.annotation.*`.
Reported as "Topl Error" by [topl](/docs/next/checker-topl).
-Experimental.
+A violation of a Topl property (user-specified).
## UNINITIALIZED_VALUE
Reported as "Uninitialized Value" by [uninit](/docs/next/checker-uninit).
diff --git a/website/docs/checker-topl.md b/website/docs/checker-topl.md
index 2a3d62a2c49..c777c2c566d 100644
--- a/website/docs/checker-topl.md
+++ b/website/docs/checker-topl.md
@@ -1,9 +1,9 @@
---
-title: "TOPL"
-description: "Detects errors based on user-provided state machines describing multi-object monitors."
+title: "Topl"
+description: "Detect errors based on user-provided state machines describing temporal properties over multiple objects."
---
-Detects errors based on user-provided state machines describing multi-object monitors.
+Detect errors based on user-provided state machines describing temporal properties over multiple objects.
Activate with `--topl`.
@@ -12,6 +12,103 @@ Supported languages:
- Java: Experimental
- C#/.Net: Experimental
+# Topl
+
+## What is it?
+
+Topl is an analysis framework, built on top of Infer, for statically finding violations of temporal properties. Many analyses can be encoded as temporal properties supported by Topl, such as taint analysis. As a simple example, suppose that we don't want a value returned by method `source()` to be sent as an argument to a method `sink()`. This can be specified as follows:
+
+```
+property Taint
+ prefix "Main"
+ start -> start: *
+ start -> tracking: source(Ret) => x := Ret
+ tracking -> error: sink(Arg, VoidRet) when x == Arg
+```
+
+This specifies an automaton called `Taint` that has three states (`start`, `tracking`, `error`). Two of those states (`start` and `error`) have special meaning; other states (`tracking`) can have any names. The first transition (`start → tracking`) is taken when a method called `source()` is called, and its return value is stored in a register called `x`; the second transition (`tracking → error`) is taken when a method called `sink()` is called, but only if its argument equals what was previously saved in register `x`.
+This property is violated in the following Java code:
+
+```
+public class Main {
+ static void f() { g(tito(source())); }
+ static void g(Object x) { h(x); }
+ static void h(Object x) { sink(x); }
+ static Object tito(Object x) { return x; }
+ static Object source() { return "dirty"; }
+ static void sink(Object x) {}
+}
+```
+
+Note that `source()` and `sink()` are not called from the same method, and that the “dirty” object is passed around a few times before finally reaching the sink. Assuming that the property is in a file `taint.topl` and the Java code in a file `Main.java`, you can invoke Infer with the following command:
+
+```
+infer --topl --topl-properties taint.topl -- javac Main.java
+```
+
+It will display the following error:
+
+```
+Main.java:2: error: Topl Error
+ property Taint reaches state error.
+ 1. public class Main {
+ 2. > static void f() { g(tito(source())); }
+ 3. static void g(Object x) { h(x); }
+ 4. static void h(Object x) { sink(x); }
+```
+
+To get a full trace, use the command
+
+```
+infer explore
+```
+
+## Specifying Properties
+
+A property is a nondeterministic automaton that can remember values in registers. An execution that drives the automaton from the start state to the error state will make Infer report an issue, and the trace that it produces will indicate which parts of the program drive which transitions of the automaton.
+
+The general form of a property is the following:
+
+```
+property *Name
+* message "Optional error message" // This line can be missing
+ prefix "Prefix" // There can be zero, one, or more prefix declarations
+ sourceState -> targetState: *Pattern*(Arg1,...,ArgN,Ret) when *Condition* => *Action*
+```
+
+The property name and the optional error message are used for reporting issues. The prefix declarations are used to simplify Patterns. The core of the property is the list of transitions.
+
+Each transition has a source state and a target state. The special transition label * means that the transition is always taken. Typically, there is a transition
+
+```
+ start -> start: *
+```
+
+meaning that the property can start anywhere, not just at the beginning of a method.
+
+Otherwise, the label on a transition contains:
+
+* a *Pattern*, which indicates what kind of instruction in the program drives this transition;
+* a list of transition variable bindings (above named Arg1, ..., but any identifier starting with uppercase letters works);
+* possibly a boolean Condition, which can refer to transition variables and to registers;
+* possibly and Action, which is a list sequence of assignments of the form *register* := *TransitionVariable* (registers do not need to be declared, and any identifier starting with a lowercase letter works).
+
+There are two types of patterns:
+
+* a regex that matches method names
+ * if the regex uses non-letters (such as dots) it must be within double-quotes; otherwise, double quotes are optional
+ * the prefix declarations are used to add potential prefixes to the regex. The combine regex is essentially “(prefix_regex_a | prefix_regex_b) transition_pattern_regex“
+ * for a method with n arguments, there must be n+1 transition variables to get a match. The first n transition variables get bound to the argument values, and the last transition variable gets bound to the return value. *This is true even for the case in which the return type is void*.
+* the special keyword **#ArrayWrite**. In that case, there should be two transition variables like “(Array, Index)” — Array gets bound to the array object, and Index gets bound to the index at which the write happens.
+
+For several examples, see https://github.com/facebook/infer/tree/master/infer/tests/codetoanalyze/java/topl
+
+## Limitations
+
+* By design, some problems may be missed. Topl is built on Pulse, which attempts to minimize false positives, at the cost of sometimes having false negatives.
+* Analysis time increases exponentially with the number of registers used in properties.
+ * In theory, there should be no significant slowdown if registers belong to different properties, but the implementation is not yet optimized.
+ * If there are many registers within the same property, then the slowdown is unavoidable (without some significant breakthrough). However, the maximum number of registers we ever used for one practical property was 3.
## List of Issue Types
diff --git a/website/static/man/next/infer-analyze.1.html b/website/static/man/next/infer-analyze.1.html
index 3059ff096dd..fd85729f3ad 100644
--- a/website/static/man/next/infer-analyze.1.html
+++ b/website/static/man/next/infer-analyze.1.html
@@ -720,9 +720,9 @@
OPTIONS
--topl
-
Activates: checker topl:
-Detects errors based on user-provided state machines
-describing multi-object monitors. (Conversely:
+
Activates: checker topl: Detect
+errors based on user-provided state machines describing
+temporal properties over multiple objects. (Conversely:
--no-topl)
Activates: checker topl:
-Detects errors based on user-provided state machines
-describing multi-object monitors. (Conversely:
+
Activates: checker topl: Detect
+errors based on user-provided state machines describing
+temporal properties over multiple objects. (Conversely:
--no-topl)
See also
diff --git a/website/static/odoc/next/infer/IBase/Checker/index.html b/website/static/odoc/next/infer/IBase/Checker/index.html
index b2ad7db3db9..db0ed01a55a 100644
--- a/website/static/odoc/next/infer/IBase/Checker/index.html
+++ b/website/static/odoc/next/infer/IBase/Checker/index.html
@@ -1,2 +1,2 @@
-
checker runs but is not expected to give reasonable results
| Support
checker is expected to give reasonable results
per-language support for each checker
type cli_flags = {
deprecated : string list;
More command-line flags, similar to ~deprecated arguments in CommandLineOption.
show_in_help : bool;
}
type kind =
| UserFacingof{
title : string;
the title of the documentation web page
markdown_body : string;
main text of the documentation
}
can report issues to users
| UserFacingDeprecatedof{
title : string;
the title of the documentation web page
markdown_body : string;
main text of the documentation
deprecation_message : string;
}
can report issues to users but should probably be deleted from infer
| Internal
Analysis that only serves other analyses. Do not use to mean experimental! Please still document experimental checkers as they will become non-experimental.
| Exercise
reserved for the "resource leak" lab exercise
type config = {
id : string;
Unique identifier. Used to generate web URLs for the documentation as well as the flag to enable this option on the command line.
checker runs but is not expected to give reasonable results
| Support
checker is expected to give reasonable results
per-language support for each checker
type cli_flags = {
deprecated : string list;
More command-line flags, similar to ~deprecated arguments in CommandLineOption.
show_in_help : bool;
}
type kind =
| UserFacingof{
title : string;
the title of the documentation web page
markdown_body : string;
main text of the documentation
}
can report issues to users
| UserFacingDeprecatedof{
title : string;
the title of the documentation web page
markdown_body : string;
main text of the documentation
deprecation_message : string;
}
can report issues to users but should probably be deleted from infer
| Internal
Analysis that only serves other analyses. Do not use to mean experimental! Please still document experimental checkers as they will become non-experimental.
| Exercise
reserved for the "resource leak" lab exercise
type config = {
id : string;
Unique identifier. Used to generate web URLs for the documentation as well as the flag to enable this option on the command line.
\ No newline at end of file
diff --git a/website/static/odoc/next/infer/IBase__Checker/index.html b/website/static/odoc/next/infer/IBase__Checker/index.html
index aa332d53b88..5028bf77629 100644
--- a/website/static/odoc/next/infer/IBase__Checker/index.html
+++ b/website/static/odoc/next/infer/IBase__Checker/index.html
@@ -1,2 +1,2 @@
-IBase__Checker (infer.IBase__Checker)
checker runs but is not expected to give reasonable results
| Support
checker is expected to give reasonable results
per-language support for each checker
type cli_flags = {
deprecated : string list;
More command-line flags, similar to ~deprecated arguments in CommandLineOption.
show_in_help : bool;
}
type kind =
| UserFacingof{
title : string;
the title of the documentation web page
markdown_body : string;
main text of the documentation
}
can report issues to users
| UserFacingDeprecatedof{
title : string;
the title of the documentation web page
markdown_body : string;
main text of the documentation
deprecation_message : string;
}
can report issues to users but should probably be deleted from infer
| Internal
Analysis that only serves other analyses. Do not use to mean experimental! Please still document experimental checkers as they will become non-experimental.
| Exercise
reserved for the "resource leak" lab exercise
type config = {
id : string;
Unique identifier. Used to generate web URLs for the documentation as well as the flag to enable this option on the command line.
checker runs but is not expected to give reasonable results
| Support
checker is expected to give reasonable results
per-language support for each checker
type cli_flags = {
deprecated : string list;
More command-line flags, similar to ~deprecated arguments in CommandLineOption.
show_in_help : bool;
}
type kind =
| UserFacingof{
title : string;
the title of the documentation web page
markdown_body : string;
main text of the documentation
}
can report issues to users
| UserFacingDeprecatedof{
title : string;
the title of the documentation web page
markdown_body : string;
main text of the documentation
deprecation_message : string;
}
can report issues to users but should probably be deleted from infer
| Internal
Analysis that only serves other analyses. Do not use to mean experimental! Please still document experimental checkers as they will become non-experimental.
| Exercise
reserved for the "resource leak" lab exercise
type config = {
id : string;
Unique identifier. Used to generate web URLs for the documentation as well as the flag to enable this option on the command line.
\ No newline at end of file
diff --git a/website/static/odoc/next/infer/IR/Procdesc/index.html b/website/static/odoc/next/infer/IR/Procdesc/index.html
index eea1b8e6249..e7fa23f11cd 100644
--- a/website/static/odoc/next/infer/IR/Procdesc/index.html
+++ b/website/static/odoc/next/infer/IR/Procdesc/index.html
@@ -1,2 +1,2 @@
-Procdesc (infer.IR.Procdesc)
Map and replace the instructions to be executed using a context that we built with previous instructions in the node. Returns true if at least one substitution occured.
Map and replace the instructions to be executed using a context that we built with previous instructions in the node. Returns true if at least one substitution occured.
\ No newline at end of file
diff --git a/website/static/odoc/next/infer/IR__Procdesc/index.html b/website/static/odoc/next/infer/IR__Procdesc/index.html
index 3ddc085b6a6..6426f69629e 100644
--- a/website/static/odoc/next/infer/IR__Procdesc/index.html
+++ b/website/static/odoc/next/infer/IR__Procdesc/index.html
@@ -1,2 +1,2 @@
-IR__Procdesc (infer.IR__Procdesc)
Map and replace the instructions to be executed using a context that we built with previous instructions in the node. Returns true if at least one substitution occured.
Map and replace the instructions to be executed using a context that we built with previous instructions in the node. Returns true if at least one substitution occured.
\ No newline at end of file
diff --git a/website/static/odoc/next/infer/TOPLlib/.dune-keep b/website/static/odoc/next/infer/Topllib/.dune-keep
similarity index 100%
rename from website/static/odoc/next/infer/TOPLlib/.dune-keep
rename to website/static/odoc/next/infer/Topllib/.dune-keep
diff --git a/website/static/odoc/next/infer/TOPLlib/Topl/index.html b/website/static/odoc/next/infer/Topllib/Topl/index.html
similarity index 84%
rename from website/static/odoc/next/infer/TOPLlib/Topl/index.html
rename to website/static/odoc/next/infer/Topllib/Topl/index.html
index 5bcf2186645..4a2ade1edb5 100644
--- a/website/static/odoc/next/infer/TOPLlib/Topl/index.html
+++ b/website/static/odoc/next/infer/Topllib/Topl/index.html
@@ -1,2 +1,2 @@
-Topl (infer.TOPLlib.Topl)
Return the automaton representing all Topl properties.
val is_active : unit -> bool
Return whether PulseTopl is active.
\ No newline at end of file
diff --git a/website/static/odoc/next/infer/TOPLlib/ToplAst/index.html b/website/static/odoc/next/infer/Topllib/ToplAst/index.html
similarity index 98%
rename from website/static/odoc/next/infer/TOPLlib/ToplAst/index.html
rename to website/static/odoc/next/infer/Topllib/ToplAst/index.html
index 0e86ff35d1b..3638b54d18b 100644
--- a/website/static/odoc/next/infer/TOPLlib/ToplAst/index.html
+++ b/website/static/odoc/next/infer/Topllib/ToplAst/index.html
@@ -1,2 +1,2 @@
-ToplAst (infer.TOPLlib.ToplAst)
\ No newline at end of file
diff --git a/website/static/odoc/next/infer/TOPLlib/ToplAstOps/index.html b/website/static/odoc/next/infer/Topllib/ToplAstOps/index.html
similarity index 80%
rename from website/static/odoc/next/infer/TOPLlib/ToplAstOps/index.html
rename to website/static/odoc/next/infer/Topllib/ToplAstOps/index.html
index a660e366117..078b385e0f3 100644
--- a/website/static/odoc/next/infer/TOPLlib/ToplAstOps/index.html
+++ b/website/static/odoc/next/infer/Topllib/ToplAstOps/index.html
@@ -1,2 +1,2 @@
-ToplAstOps (infer.TOPLlib.ToplAstOps)
Module TOPLlib.ToplAstOps
val pp_label : Stdlib.Format.formatter ->ToplAst.label option-> unit
\ No newline at end of file
+ToplAstOps (infer.Topllib.ToplAstOps)
Module Topllib.ToplAstOps
val pp_label : Stdlib.Format.formatter ->ToplAst.label option-> unit
\ No newline at end of file
diff --git a/website/static/odoc/next/infer/TOPLlib/ToplAutomaton/index.html b/website/static/odoc/next/infer/Topllib/ToplAutomaton/index.html
similarity index 96%
rename from website/static/odoc/next/infer/TOPLlib/ToplAutomaton/index.html
rename to website/static/odoc/next/infer/Topllib/ToplAutomaton/index.html
index 03d7de99400..3c4ae66da60 100644
--- a/website/static/odoc/next/infer/TOPLlib/ToplAutomaton/index.html
+++ b/website/static/odoc/next/infer/Topllib/ToplAutomaton/index.html
@@ -1,2 +1,2 @@
-ToplAutomaton (infer.TOPLlib.ToplAutomaton)
val pp_transition : Stdlib.Format.formatter ->transition-> unit
\ No newline at end of file
diff --git a/website/static/odoc/next/infer/TOPLlib/ToplLexer/index.html b/website/static/odoc/next/infer/Topllib/ToplLexer/index.html
similarity index 93%
rename from website/static/odoc/next/infer/TOPLlib/ToplLexer/index.html
rename to website/static/odoc/next/infer/Topllib/ToplLexer/index.html
index 74e05374ee3..b83b85ec821 100644
--- a/website/static/odoc/next/infer/TOPLlib/ToplLexer/index.html
+++ b/website/static/odoc/next/infer/Topllib/ToplLexer/index.html
@@ -1,2 +1,2 @@
-ToplLexer (infer.TOPLlib.ToplLexer)
\ No newline at end of file
diff --git a/website/static/odoc/next/infer/TOPLlib/ToplParser/index.html b/website/static/odoc/next/infer/Topllib/ToplParser/index.html
similarity index 97%
rename from website/static/odoc/next/infer/TOPLlib/ToplParser/index.html
rename to website/static/odoc/next/infer/Topllib/ToplParser/index.html
index a1b670a3b9a..63173571e12 100644
--- a/website/static/odoc/next/infer/TOPLlib/ToplParser/index.html
+++ b/website/static/odoc/next/infer/Topllib/ToplParser/index.html
@@ -1,2 +1,2 @@
-ToplParser (infer.TOPLlib.ToplParser)
Module TOPLlib.ToplParser
type token =
| WHEN
| UIDof string
| STRINGof string
| STAR
| SEMI
| RP
| RC
| PROPERTY
| PREFIX
| NONDET
| NE
| MESSAGE
| LT
| LP
| LIDof string
| LE
| LC
| INTEGERof int
| INDENTof int
| GT
| GE
| EQ
| EOF
| COMMA
| COLONEQ
| COLON
| ARROWARROW
| ARROW
| ARRAYWRITE
| AND
exceptionError
val properties : (Stdlib.Lexing.lexbuf ->token)-> Stdlib.Lexing.lexbuf ->ToplAst.t list
\ No newline at end of file
+ToplParser (infer.Topllib.ToplParser)
Module Topllib.ToplParser
type token =
| WHEN
| UIDof string
| STRINGof string
| STAR
| SEMI
| RP
| RC
| PROPERTY
| PREFIX
| NONDET
| NE
| MESSAGE
| LT
| LP
| LIDof string
| LE
| LC
| INTEGERof int
| INDENTof int
| GT
| GE
| EQ
| EOF
| COMMA
| COLONEQ
| COLON
| ARROWARROW
| ARROW
| ARRAYWRITE
| AND
exceptionError
val properties : (Stdlib.Lexing.lexbuf ->token)-> Stdlib.Lexing.lexbuf ->ToplAst.t list
\ No newline at end of file
diff --git a/website/static/odoc/next/infer/TOPLlib/index.html b/website/static/odoc/next/infer/Topllib/index.html
similarity index 88%
rename from website/static/odoc/next/infer/TOPLlib/index.html
rename to website/static/odoc/next/infer/Topllib/index.html
index 0a7c49a9c21..92ca68c2a74 100644
--- a/website/static/odoc/next/infer/TOPLlib/index.html
+++ b/website/static/odoc/next/infer/Topllib/index.html
@@ -1,2 +1,2 @@
-TOPLlib (infer.TOPLlib)
\ No newline at end of file
diff --git a/website/static/odoc/next/infer/TOPLlib__Topl/.dune-keep b/website/static/odoc/next/infer/Topllib__Topl/.dune-keep
similarity index 100%
rename from website/static/odoc/next/infer/TOPLlib__Topl/.dune-keep
rename to website/static/odoc/next/infer/Topllib__Topl/.dune-keep
diff --git a/website/static/odoc/next/infer/TOPLlib__Topl/index.html b/website/static/odoc/next/infer/Topllib__Topl/index.html
similarity index 67%
rename from website/static/odoc/next/infer/TOPLlib__Topl/index.html
rename to website/static/odoc/next/infer/Topllib__Topl/index.html
index da4a841e1ab..050c483a94d 100644
--- a/website/static/odoc/next/infer/TOPLlib__Topl/index.html
+++ b/website/static/odoc/next/infer/Topllib__Topl/index.html
@@ -1,2 +1,2 @@
-TOPLlib__Topl (infer.TOPLlib__Topl)
Return the automaton representing all Topl properties.
val is_active : unit -> bool
Return whether PulseTopl is active.
\ No newline at end of file
diff --git a/website/static/odoc/next/infer/TOPLlib__ToplAst/.dune-keep b/website/static/odoc/next/infer/Topllib__ToplAst/.dune-keep
similarity index 100%
rename from website/static/odoc/next/infer/TOPLlib__ToplAst/.dune-keep
rename to website/static/odoc/next/infer/Topllib__ToplAst/.dune-keep
diff --git a/website/static/odoc/next/infer/TOPLlib__ToplAst/index.html b/website/static/odoc/next/infer/Topllib__ToplAst/index.html
similarity index 98%
rename from website/static/odoc/next/infer/TOPLlib__ToplAst/index.html
rename to website/static/odoc/next/infer/Topllib__ToplAst/index.html
index d9b371cacce..2149d7ecd54 100644
--- a/website/static/odoc/next/infer/TOPLlib__ToplAst/index.html
+++ b/website/static/odoc/next/infer/Topllib__ToplAst/index.html
@@ -1,2 +1,2 @@
-TOPLlib__ToplAst (infer.TOPLlib__ToplAst)
\ No newline at end of file
diff --git a/website/static/odoc/next/infer/TOPLlib__ToplAstOps/.dune-keep b/website/static/odoc/next/infer/Topllib__ToplAstOps/.dune-keep
similarity index 100%
rename from website/static/odoc/next/infer/TOPLlib__ToplAstOps/.dune-keep
rename to website/static/odoc/next/infer/Topllib__ToplAstOps/.dune-keep
diff --git a/website/static/odoc/next/infer/TOPLlib__ToplAstOps/index.html b/website/static/odoc/next/infer/Topllib__ToplAstOps/index.html
similarity index 66%
rename from website/static/odoc/next/infer/TOPLlib__ToplAstOps/index.html
rename to website/static/odoc/next/infer/Topllib__ToplAstOps/index.html
index 494cc2c8874..9816c8e483f 100644
--- a/website/static/odoc/next/infer/TOPLlib__ToplAstOps/index.html
+++ b/website/static/odoc/next/infer/Topllib__ToplAstOps/index.html
@@ -1,2 +1,2 @@
-TOPLlib__ToplAstOps (infer.TOPLlib__ToplAstOps)
\ No newline at end of file
diff --git a/website/static/odoc/next/infer/TOPLlib__ToplAutomaton/.dune-keep b/website/static/odoc/next/infer/Topllib__ToplAutomaton/.dune-keep
similarity index 100%
rename from website/static/odoc/next/infer/TOPLlib__ToplAutomaton/.dune-keep
rename to website/static/odoc/next/infer/Topllib__ToplAutomaton/.dune-keep
diff --git a/website/static/odoc/next/infer/TOPLlib__ToplAutomaton/index.html b/website/static/odoc/next/infer/Topllib__ToplAutomaton/index.html
similarity index 89%
rename from website/static/odoc/next/infer/TOPLlib__ToplAutomaton/index.html
rename to website/static/odoc/next/infer/Topllib__ToplAutomaton/index.html
index 1f02add1b76..34e143c56ac 100644
--- a/website/static/odoc/next/infer/TOPLlib__ToplAutomaton/index.html
+++ b/website/static/odoc/next/infer/Topllib__ToplAutomaton/index.html
@@ -1,2 +1,2 @@
-TOPLlib__ToplAutomaton (infer.TOPLlib__ToplAutomaton)
val pp_transition : Stdlib.Format.formatter ->transition-> unit
\ No newline at end of file
diff --git a/website/static/odoc/next/infer/TOPLlib__ToplLexer/.dune-keep b/website/static/odoc/next/infer/Topllib__ToplLexer/.dune-keep
similarity index 100%
rename from website/static/odoc/next/infer/TOPLlib__ToplLexer/.dune-keep
rename to website/static/odoc/next/infer/Topllib__ToplLexer/.dune-keep
diff --git a/website/static/odoc/next/infer/TOPLlib__ToplLexer/index.html b/website/static/odoc/next/infer/Topllib__ToplLexer/index.html
similarity index 77%
rename from website/static/odoc/next/infer/TOPLlib__ToplLexer/index.html
rename to website/static/odoc/next/infer/Topllib__ToplLexer/index.html
index e9620344591..dd19a513e43 100644
--- a/website/static/odoc/next/infer/TOPLlib__ToplLexer/index.html
+++ b/website/static/odoc/next/infer/Topllib__ToplLexer/index.html
@@ -1,2 +1,2 @@
-TOPLlib__ToplLexer (infer.TOPLlib__ToplLexer)
\ No newline at end of file
diff --git a/website/static/odoc/next/infer/TOPLlib__ToplParser/.dune-keep b/website/static/odoc/next/infer/Topllib__ToplParser/.dune-keep
similarity index 100%
rename from website/static/odoc/next/infer/TOPLlib__ToplParser/.dune-keep
rename to website/static/odoc/next/infer/Topllib__ToplParser/.dune-keep
diff --git a/website/static/odoc/next/infer/TOPLlib__ToplParser/index.html b/website/static/odoc/next/infer/Topllib__ToplParser/index.html
similarity index 95%
rename from website/static/odoc/next/infer/TOPLlib__ToplParser/index.html
rename to website/static/odoc/next/infer/Topllib__ToplParser/index.html
index b939e5d7346..53316c21835 100644
--- a/website/static/odoc/next/infer/TOPLlib__ToplParser/index.html
+++ b/website/static/odoc/next/infer/Topllib__ToplParser/index.html
@@ -1,2 +1,2 @@
-TOPLlib__ToplParser (infer.TOPLlib__ToplParser)
Module TOPLlib__ToplParser
type token =
| WHEN
| UIDof string
| STRINGof string
| STAR
| SEMI
| RP
| RC
| PROPERTY
| PREFIX
| NONDET
| NE
| MESSAGE
| LT
| LP
| LIDof string
| LE
| LC
| INTEGERof int
| INDENTof int
| GT
| GE
| EQ
| EOF
| COMMA
| COLONEQ
| COLON
| ARROWARROW
| ARROW
| ARRAYWRITE
| AND
exceptionError
val properties : (Stdlib.Lexing.lexbuf ->token)-> Stdlib.Lexing.lexbuf ->TOPLlib.ToplAst.t list
\ No newline at end of file
+Topllib__ToplParser (infer.Topllib__ToplParser)
Module Topllib__ToplParser
type token =
| WHEN
| UIDof string
| STRINGof string
| STAR
| SEMI
| RP
| RC
| PROPERTY
| PREFIX
| NONDET
| NE
| MESSAGE
| LT
| LP
| LIDof string
| LE
| LC
| INTEGERof int
| INDENTof int
| GT
| GE
| EQ
| EOF
| COMMA
| COLONEQ
| COLON
| ARROWARROW
| ARROW
| ARRAYWRITE
| AND
exceptionError
val properties : (Stdlib.Lexing.lexbuf ->token)-> Stdlib.Lexing.lexbuf ->Topllib.ToplAst.t list
\ No newline at end of file
diff --git a/website/static/odoc/next/infer/index.html b/website/static/odoc/next/infer/index.html
index 0d7360b44bc..2fbc418b532 100644
--- a/website/static/odoc/next/infer/index.html
+++ b/website/static/odoc/next/infer/index.html
@@ -1,2 +1,2 @@
-index (infer.index)
infer index
Library infer.ASTLanguage
The entry point of this library is the module: ASTLanguage.
Library infer.ATDGenerated
The entry point of this library is the module: ATDGenerated.
Library infer.Absint
The entry point of this library is the module: Absint.
Library infer.BO
The entry point of this library is the module: BO.
Library infer.Backend
The entry point of this library is the module: Backend.
Library infer.Biabduction
The entry point of this library is the module: Biabduction.
Library infer.CStubs
The entry point of this library is the module: CStubs.
Library infer.Checkers
The entry point of this library is the module: Checkers.
Library infer.ClangFrontend
The entry point of this library is the module: ClangFrontend.
Library infer.ClangUnitTests
The entry point of this library is the module: ClangUnitTests.
Library infer.Concurrency
The entry point of this library is the module: Concurrency.
Library infer.Costlib
The entry point of this library is the module: Costlib.
Library infer.Dotnet
The entry point of this library is the module: Dotnet.
Library infer.IBase
The entry point of this library is the module: IBase.
Library infer.IR
The entry point of this library is the module: IR.
Library infer.IStdlib
The entry point of this library is the module: IStdlib.
Library infer.Integration
The entry point of this library is the module: Integration.
Library infer.JavaFrontend
The entry point of this library is the module: JavaFrontend.
Library infer.Labs
The entry point of this library is the module: Labs.
Library infer.Nullsafe
The entry point of this library is the module: Nullsafe.