Summary: Previously the JSON parser only accepted record fields if they appeared directly under the record. With this change it is possible to have record fields wrapped into typed record fields.
Reviewed By: mmarescotti
Differential Revision: D30132727
fbshipit-source-id: eb9e928b2
Summary: In map expressions, associations of the form `K := V` should only be accepted if it is a map update (expression is not empty), and should not be accepted for map creation. This is because such associations check if the key actually exist, which obviously does not hold during map creation. See also [documentation](https://erlang.org/doc/apps/erts/absform.html#expressions). We already had this check for maps in guards, but forgot to include it for maps in expressions. Fixed it now.
Reviewed By: rgrig
Differential Revision: D30103350
fbshipit-source-id: 39973a137
Summary: Report `badrecord` errors with Pulse when trying to access or update a record with a wrong name.
Reviewed By: rgrig
Differential Revision: D30068424
fbshipit-source-id: b88abb7ca
Summary:
Add support for Erlang records, including:
- Parsing record definitions, storing info in environment
- Record index expressions and patterns
- Record creation expression, including initializers
- Record update expressions and patterns
- Record field access expressions
- Pulse models
The key idea is to translate records to tagged tuples (just as Erlang does under the hood), but this requires some bookkeeping to figure out which field maps to which tuple element.
Reviewed By: rgrig
Differential Revision: D29991819
fbshipit-source-id: a1c713b41
Summary: Nil insertion into collection tests are not c++ specific, so also moving them into objc folder.
Reviewed By: skcho
Differential Revision: D30013858
fbshipit-source-id: d103a69ef
Summary:
In D29736444 (320c82d9ad), we added an ad-hoc simplification of formula. This diff reverts the diff and addresses the issue in the normalization logic.
Problem:
Before the D29736444 (320c82d9ad) diff, given `p1=p2+0;`, Pulse could not reason correctly that the pointers `p1` and `p2` are alias. While we tried to solve the issue by an ad-hoc simplification (addressing it as `p1=p2;`), the real bug was in the normalization logic.
https://www.internalfb.com/code/infer/[62c8b92c390587538b9e16032b72af56efe2b527]/infer/src/pulse/PulseOperations.ml?lines=270-276
Here, it makes a new value of `binop_addr` and returns it as a result of a binary operation. However, inside `PulseArithmetic.eval_binop`, if it finds an alias between `binop_addr` and another one `alias_addr`, it replaces all `binop_addr` in `astate` into the `alias_addr`. Thus, the last line returns `binop_addr` as a result, but there is no usage of which inside `astate`.
As a solution, we replaced `binop_addr` too, when needed.
Reviewed By: da319
Differential Revision: D29878980
fbshipit-source-id: 96a35bf16
Summary: Add support for tuples, including expressions, pattern matching and pulse models. Tuples are modeled similarly to `Cons` (lists): they have a dynamic type (including the size of the tuple) and elements as fields.
Reviewed By: mmarescotti
Differential Revision: D29875650
fbshipit-source-id: f0262a42c
Summary:
Ondemand should not analyse a pre-analysed CFG so we should never load a summary to get its CFG in Ondemand.
The only exception is if the function is a model, where its (pre-analysed) CFG only lives in a summary.
This diff eliminates the general look for a summary and only uses it if the function is a model, otherwise it looks in the capture DB.
Reviewed By: da319
Differential Revision: D29932885
fbshipit-source-id: 781ddf51d
Summary:
Ondemand looks at the attributes in the summary of a function in preference to those in the capture DB, in order to decide whether a function needs to be analysed. This is unnecessary and introduces non-determinism (whether the summary has been written is a race condition; attributes may differ from a pre-analysed CFG vs captured).
Switch to only looking at the attributes column in the capture DB.
Reviewed By: da319
Differential Revision: D29932634
fbshipit-source-id: 8d7d1b145
Summary:
Dynamic dispatch in java requires specialisation of models. Models do not have a CFG, nor attributes, in the capture DB, so the solution til now was to get those from the summary of the model.
Each code path (CFG, attributes) could introduce non-determinism by allowing summaries to mask functions in the capture DB, and doing so depending on race conditions of the analysis (whether a summary has been written or not), as well as by the fact that CFGs from the capture DB are not pre-analysed, while summary CFGs are.
This diff eliminates both code path usages in specialisation by strictly separating functions into captured functions and models. Other summaries are never consulted, and thus cannot introduce non-determinism through timing.
NB model specialisation for clang models has been disabled in the past.
Reviewed By: da319
Differential Revision: D29915082
fbshipit-source-id: 313a60e17
Summary: Use the JSON build report to figure out where each build output is instead of parsing the output of buck.
Reviewed By: da319
Differential Revision: D29935374
fbshipit-source-id: f08f68889
Summary: `std::unique_lock<...> bla()` is a valid call but which associates the guard object with no mutex. Silence the errors on such calls.
Reviewed By: da319
Differential Revision: D29937496
fbshipit-source-id: 7600200db
Summary: Add some tests for lists: nil, cons, and some basic pattern matching. We can extend this suite later with more features on lists (e.g. concatenation).
Reviewed By: skcho
Differential Revision: D29844279
fbshipit-source-id: 62c8b92c3
Summary:
`AnalysisCallbacks.get_proc_desc` potentially introduces non-determinism because it first looks for the `proc_desc` in the capture DB and if absent it tries to retrieve it from a summary.
The problem is the two proc descs are generally different, as the one in the summary is preanalysed and the one in the capture DB is not.
Unless the caller specifically needs a preanalysed `procdesc`, calls to `AnalysisCallbacks.get_proc_desc` should be replaced with `Procdesc.load`.
Reviewed By: skcho
Differential Revision: D29827647
fbshipit-source-id: 8b1dc289c
Summary:
`AnalysisCallbacks.get_proc_desc` potentially introduces non-determinism because it first looks for the `proc_desc` in the capture DB and if absent it tries to retrieve it from a summary.
The problem is the two proc descs are generally different, as the one in the summary is preanalysed and the one in the capture DB is not.
Unless the caller specifically needs a preanalysed `procdesc`, calls to `AnalysisCallbacks.get_proc_desc` should be replaced with `Procdesc.load`.
Reviewed By: skcho
Differential Revision: D29827459
fbshipit-source-id: 4373825d3
Summary:
`AnalysisCallbacks.get_proc_desc` potentially introduces non-determinism because it first looks for the `proc_desc` in the capture DB and if absent it tries to retrieve it from a summary.
The problem is the two proc descs are generally different, as the one in the summary is preanalysed and the one in the capture DB is not.
Unless the caller specifically needs a preanalysed `procdesc`, calls to `AnalysisCallbacks.get_proc_desc` should be replaced with `Procdesc.load`.
Reviewed By: skcho
Differential Revision: D29826482
fbshipit-source-id: f8c7cb243
Summary:
`AnalysisCallbacks.proc_resolve_attributes` introduces non-determinism because it first looks for the attributes in a (procdesc in a) summary and if it doesn't find it then returns the value in the attribute column from the capture DB.
The problem is:
- the main factor affecting the existence of a summary on-disk is timing;
- the two proc descs are generally different, as the one in the summary is preanalysed and the one in the capture DB is not;
- this extends to the attributes included in the proc desc in some cases.
The plan is to eliminate these calls one by one, replacing with `Attributes.load` which only looks at the capture DB attribute column.
Reviewed By: skcho
Differential Revision: D29817582
fbshipit-source-id: 24f9dfcc3
Summary:
`AnalysisCallbacks.proc_resolve_attributes` introduces non-determinism because it first looks for the attributes in a (procdesc in a) summary and if it doesn't find it then returns the value in the attribute column from the capture DB.
The problem is:
- the main factor affecting the existence of a summary on-disk is timing;
- the two proc descs are generally different, as the one in the summary is preanalysed and the one in the capture DB is not;
- this extends to the attributes included in the proc desc in some cases.
The plan is to eliminate these calls one by one, replacing with `Attributes.load` which only looks at the capture DB attribute column.
Reviewed By: skcho
Differential Revision: D29817404
fbshipit-source-id: b3fe8ec4d
Summary:
`AnalysisCallbacks.proc_resolve_attributes` introduces non-determinism because it first looks for the attributes in a (procdesc in a) summary and if it doesn't find it then returns the value in the attribute column from the capture DB.
The problem is:
- the main factor affecting the existence of a summary on-disk is timing;
- the two proc descs are generally different, as the one in the summary is preanalysed and the one in the capture DB is not;
- this extends to the attributes included in the proc desc in some cases.
The plan is to eliminate these calls one by one, replacing with `Attributes.load` which only looks at the capture DB attribute column.
Reviewed By: skcho
Differential Revision: D29816458
fbshipit-source-id: 681c55f4c
Summary:
`AnalysisCallbacks.proc_resolve_attributes` introduces non-determinism because it first looks for the attributes in a (procdesc in a) summary and if it doesn't find it then returns the value in the attribute column from the capture DB.
The problem is:
- the main factor affecting the existence of a summary on-disk is timing;
- the two proc descs are generally different, as the one in the summary is preanalysed and the one in the capture DB is not;
- this extends to the attributes included in the proc desc in some cases.
The plan is to eliminate these calls one by one, replacing with `Attributes.load` which only looks at the capture DB attribute column.
Reviewed By: skcho
Differential Revision: D29816411
fbshipit-source-id: d06c4bd48
Summary:
`AnalysisCallbacks.proc_resolve_attributes` introduces non-determinism because it first looks for the attributes in a (procdesc in a) summary and if it doesn't find it then returns the value in the attribute column from the capture DB.
The problem is:
- the main factor affecting the existence of a summary on-disk is timing;
- the two proc descs are generally different, as the one in the summary is preanalysed and the one in the capture DB is not;
- this extends to the attributes included in the proc desc in some cases.
The plan is to eliminate these calls one by one, replacing with `Attributes.load` which only looks at the capture DB attribute column.
Reviewed By: skcho
Differential Revision: D29816181
fbshipit-source-id: e7a2f809c
Summary: Add support for the xor operator by reducing `(X xor Y)` to `(X and not Y) or (not X and Y)`. Alternatively, `(X != Y)` could have been used but that might not be safe since SIL models Booleans with integers.
Reviewed By: skcho
Differential Revision: D29816793
fbshipit-source-id: 2496b718b
Summary: Add support for short circuit counterparts (andalso, orelse) of the logic operators (and, or).
Reviewed By: skcho
Differential Revision: D29815177
fbshipit-source-id: 98d28deed
Summary: There are multiple operators in Erlang that require special treatment and cannot be simply mapped to a SIL operator (for example andalso, orelse, exactly equal, xor). Therefore it is not practical to have a helper function mapping these operators to SIL operators.
Reviewed By: skcho
Differential Revision: D29814373
fbshipit-source-id: 892219fd3
Summary: Pulse evaluated (e1+e2) as a new value that is a sum of evaluation results of e1 and e2. However, when e2 is known as zero, we can have a simpler evaluation result without introducing the new value. This diff returns the evaluation result of e1 when e2 is known as zero.
Reviewed By: ngorogiannis
Differential Revision: D29736444
fbshipit-source-id: d5ce5a60e
Summary:
This call back introduces non-determinism because it first looks for the proc desc in a summary and if it doesn't find it then returns the one from the capture DB.
The problem is:
- the main factor affecting the existence of a summary on-disk is timing;
- the two proc descs are generally different, as the one in the summary is preanalysed and the one in the capture DB is not;
- this extends to the attributes included in the proc desc potentially.
The plan is to eliminate these calls one by one using the CI for correctness.
Reviewed By: skcho
Differential Revision: D29792603
fbshipit-source-id: 129054541
Summary:
This call back introduces non-determinism because it first looks for the proc desc in a summary and if it doesn't find it then returns the one from the capture DB.
The problem is:
- the main factor affecting the existence of a summary on-disk is timing;
- the two proc descs are generally different, as the one in the summary is preanalysed and the one in the capture DB is not;
- this extends to the attributes included in the proc desc potentially.
The plan is to eliminate these calls one by one using the CI for correctness.
Reviewed By: skcho
Differential Revision: D29793530
fbshipit-source-id: 6d9269cee
Summary:
This call back introduces non-determinism because it first looks for the proc desc in a summary and if it doesn't find it then returns the one from the capture DB.
The problem is:
- the main factor affecting the existence of a summary on-disk is timing;
- the two proc descs are generally different, as the one in the summary is preanalysed and the one in the capture DB is not;
- this extends to the attributes included in the proc desc potentially.
The plan is to eliminate these calls one by one using the CI for correctness.
Reviewed By: skcho
Differential Revision: D29792757
fbshipit-source-id: 744472950
Summary: Previously we just reported NONEXHAUSTIVE_PATTERN_MATCH, which was (1) not correct because not only patterns can cause nonexhaustive behavior, but also guards, and (2) the Erlang runtime reports errors more precisely, indicating whether the nonexhaustive behavior occurs with `if`, `case`, functions or match expressions.
Reviewed By: rgrig
Differential Revision: D29681637
fbshipit-source-id: 74a25b371
Summary:
This fixes a bug that caused imprecise tracking of dynamic types.
Suppose we knew
term_eqs:
(x instanceof T)=v1
(y instanceof T)=v2
0=v2
attrs:
x has DynamicType T
y has DynamicType T
The simplification used to produce
term_eqs:
1=v1
0=v2
That's because term_eqs is a map and 1 can appear at most once as a key.
Note that the missing fact (1=v2) contradicts (0=v2). The imprecision
came from not noticing such contradictions. Most of these imprecisions
were observed in Erlang tests.
The fix is to go from using Term.VarMap to the smarter functions in
PulseFormula.Normalizer.
Reviewed By: jvillard
Differential Revision: D29541209
fbshipit-source-id: e4e077c87
Summary: Add support for guards, both in function clauses and case clauses.
Reviewed By: rgrig
Differential Revision: D29634937
fbshipit-source-id: 5a9f8ec2d
Summary: Small refactor to make the code more readable and possibly reusable in the future.
Reviewed By: rgrig
Differential Revision: D29614102
fbshipit-source-id: 3173b945a
Summary: Add support for *unary minus* and *logical not* in the Erlang translation, both as expression (e.g., `X = -Y`) and pattern (e.g., `case X of -3 -> ...`).
Reviewed By: rgrig
Differential Revision: D29582176
fbshipit-source-id: 17ef89496
Summary: The --suffix option of mktemp is not available on macos. Changed to rename the temp file created by adding the extension.
Reviewed By: skcho
Differential Revision: D29587977
fbshipit-source-id: b7a5adda8
Summary: Group tests based on the different constructs: functions, case expressions and match expressions.
Reviewed By: rgrig
Differential Revision: D29559982
fbshipit-source-id: eb645ed8d
Summary: Add some tests for binary expressions. The idea is that tests come in pairs: in both cases we do the same calculations, one is asserting the good result and one is not, where only the latter should trigger a warning.
Reviewed By: rgrig
Differential Revision: D29556364
fbshipit-source-id: 5b601d141
Summary:
The creation of the inital state has evolved several times recently,
time for a refactor:
- do not create then pass the initial state around when callees can
create it instead
- slightly hackish assertions that creating the initial state conditions
cannot fail to simplify the types (could eventually be moved in
AbductiveDomain.ml to avoid breaking abstraction layers like this, but
trivial enough that it doesn't really matter I think)
Reviewed By: skcho
Differential Revision: D29550319
fbshipit-source-id: 63919ae71