Summary:
This diff converts the Eradicate and Checkers tests to the new direct test format, which does not rely on buck or junit.
A self-contained Makefile is used to compile and analyze the test files, including all the dependencies, and a special option in InferPrint is used to produce a file of expected results `issues.exp`, which is checked into the repository.
Having an explicit Makefile makes it easy to edit and compile one set of test files in isolation, to investigate test failures, do debugging, etc.
A bunch of boilerplate code is removed. For example, the single file of expected results `issues.exp` replaces the 1.5K LOC in `endtoend/java/eradicate`.
Reviewed By: jvillard
Differential Revision: D3764632
fbshipit-source-id: 6c68ab8
Summary:
1. Add capability to clang frontend to replace some function calls with another SIL code based on `__deprecated__` attribute.
2. Given this capability, use those attributes for shared_ptr getters to generate `Sil.Load` instruction instead of method call
3. Add test that mimics shared_ptr model, but it doesn't have that much scary C++ templated code
Reviewed By: jvillard, jberdine
Differential Revision: D3729176
fbshipit-source-id: 2a330d5
Summary:
Make std::shared_ptr<T> translated as T* inside infer. This will make reporting better
since smart pointers are really pointers not structs - this form is much easier for the analyzer to understand.
This requires changes to the model of shared_ptr as well.
Reviewed By: jvillard
Differential Revision: D3587255
fbshipit-source-id: b86fb36
Summary:
Infer doesn't go looking into field values when looking for unsigned
expressions, which could cause some unintended reports.
Reviewed By: sblackshear
Differential Revision: D3724232
fbshipit-source-id: 9c4cd97
Summary:
This helps avoid some unintended reports where the actual is known to point to
a specific object before a call to a skipped function. This requires a change
in the plugin to export more info about const types.
Reviewed By: dulmarod
Differential Revision: D3711901
fbshipit-source-id: f5c903e
Summary:
Adding a new mode linters. Now if the analyzer is linters, we do the linters and don't translate,
then, if the analyzer is Infer, we do the translation and the backend and not the linters checks, and the
default is that we do capture, backend and lint checks.
Made the tests separated, which saves time and also shows that the linters mode works.
Reviewed By: jvillard
Differential Revision: D3723472
fbshipit-source-id: 9d828d8
Summary: With this approach, all the global consts will be inlined in the places where they are used.
Reviewed By: dulmarod
Differential Revision: D3703133
fbshipit-source-id: 3c19479
Summary:
Make checks context-aware, to increase flexibility.
As an example application of this change, whenever an atomic property is accessed from within a synchronized block, skip reporting a `DIRECT_ATOMIC_PROPERTY_ACCESS` warning.
Reviewed By: jvillard
Differential Revision: D3648831
fbshipit-source-id: c033f45
Summary: Follow up D3579581. We forget about memory acquired in resources with assumption that developers use raii and free memory in destructors.
Reviewed By: jvillard
Differential Revision: D3614056
fbshipit-source-id: 08fa112
Summary:
Previously, we would translate `throw` with `return`. However, `throw` in
ObjC/C++ is often used to mean "abort". We now translate `throw` the same as
`exit` to prune these paths.
Reviewed By: akotulski
Differential Revision: D3594156
fbshipit-source-id: 81083bb
Summary:
Minor stuff:
- GCCAst -> GCCAsm
- separate constants and mutable global state in cFrontend_config
- alphabetical ordering in cFrontend_config
Reviewed By: akotulski
Differential Revision: D3593858
fbshipit-source-id: 6f4d9c3
Summary:
No longer allow pointer types to be passed inside var_exp_typ. We used to accept both forms,
but it won't be possible any longer once shared_ptr becomes pointer type.
Reviewed By: dulmarod
Differential Revision: D3593003
fbshipit-source-id: a830914
Summary:
When analyzing C model in C++, we were seeing some SKIP function triggered by generated constructors/operators= for C structs.
In C they weren't present, but in C++ compiler generates them for us. To avoid this (and future) problems
with models, translate all functions that are needed when computing the model
Reviewed By: dulmarod
Differential Revision: D3561873
fbshipit-source-id: f8ad2a0
Summary:
Backend has the same treatment for all Typ.Int types and so UnaryOperator
should be translated the same for all of them
Reviewed By: jvillard
Differential Revision: D3534277
fbshipit-source-id: 8569b65
Summary:
Call infer with `--unsafe-malloc` or set `unsafe-malloc: true,` in .inferconfig to
have infer assume that `malloc()` never returns null.
closes#389
Reviewed By: jberdine
Differential Revision: D3522169
fbshipit-source-id: 6b88a16
Summary:
This call was producing confusing false positives when deleted object was possible to be null.
Changing frontend to add that check is not trivial so I turned it off for now (we don't handle
destructors in other cases anyway)
Reviewed By: dulmarod
Differential Revision: D3509354
fbshipit-source-id: c23dc81
Summary:
When clang instantiates template function with argument pack, it will
give the same name to all parameters coming from the pack. To avoid
name collisions, always add index of argument's position to mangled part
of the variable.
Seemingly unrelated changes are to make existing tests pass (don't use
simple variable name where it matters)
Reviewed By: dulmarod
Differential Revision: D3503608
fbshipit-source-id: 794093a
Summary: Those functions have simple enough implementations for infer to understand them
Reviewed By: jvillard
Differential Revision: D3463084
fbshipit-source-id: f84160f
Summary:
Assume that std::vector::resize will always create nonempty vector. While this is clearly
wrong for resize(0), it removes many FPs for `resize(n)` calls, where value of `n` is unknown.
Without it, infer was thinking that `n` could be 0 and reported empty vector access.
Reviewed By: jvillard
Differential Revision: D3424355
fbshipit-source-id: cb476de
Summary:
The extra dereference in stmtexpr was wrong. When a dereference is needed, we have a cast.
This was causing one dereference too many, and creating wrong results.
Reviewed By: akotulski
Differential Revision: D3393294
fbshipit-source-id: 7a1ec8e
Summary:
Now all code in tests is reachable by the analyzer which increases
test quality.
Reviewed By: dulmarod
Differential Revision: D3358591
fbshipit-source-id: d54877e
Summary:
Pass object by reference every time struct object is passed by value
in C++. Do it only for C++/objC++ where we have guarantee that the
object which is passed will be temporary one (created by copy constructor).
Reviewed By: jberdine
Differential Revision: D3346271
fbshipit-source-id: d3e5daa
Summary:
Make analyzer find out when null dereference comes from std::vector method.
If it does, it means that it's really empty vector access (due to the
way infer models std::vector)
Reviewed By: sblackshear
Differential Revision: D3327933
fbshipit-source-id: b9e11d6
Summary:
Turns out, analyzer was getting confused with complicated
model and it was reporting empty access in places it
shouldn't. Fixing backend is not trivial (tracing mode is the answer),
but the model can be simplified.
It introduces the problem that get() method doesn't return fresh value
every time, but we should be able to change backend later to deal with it.
Reviewed By: sblackshear
Differential Revision: D3328228
fbshipit-source-id: dddbaf8
Summary:
Part of the migration of .inferconfig-specific options into options accepted
both by .inferconfig and the CLI.
Reviewed By: jberdine
Differential Revision: D3304783
fbshipit-source-id: 4a7ee6f
Summary:
Create model of C++ std::vector to find occurrences when vector which might be empty is accessed. Do it by triggering null dereference every time empty vector access is performed.
Note: model will be used only when c++11 (or c++14) are used.
Reviewed By: sblackshear
Differential Revision: D3276203
fbshipit-source-id: 420a95a
Summary:
The philosophy of the tracing mode reporting is to not report the errors in a method if reaching this error does depend on information that can be false at call site. Typically with:
void foo(Object obj, int x) {
if (x == 3) {
obj.toString();
}
}
it may be that we always call `foo` with a non-null parameter or `x != 3`.
Thechnically, the reporting code matches the pairs of the form (precondition, error) and filtering out the cases where the precondtions was not imposing constraints on the calling context, and report the other cases. So the NPE could be reported in the following case:
void bar() {
foo(null, 3);
}
However, we were missing the case where there was anyway no way to call a method in a safe way, i.e. all the preconditions were of the form: (precondition, error), for example:
void baz(boolean b) {
if (b) {
foo(null, 3);
} else {
foo(null, 3);
}
}
In that case, the summary is of the form
PRE (1): b = false
POST: NullPointerException
PRE (2): b = true
POST: NullPointerException
In which case it is legit to report `NullPointerException` in `baz`.
Reviewed By: sblackshear, jberdine
Differential Revision: D3220501
fb-gh-sync-id: 7fb7d70
fbshipit-source-id: 7fb7d70
Summary: Example of dynamic dispatch with interfaces were already working. Adding some tests now so that we don't break this.
Reviewed By: sblackshear
Differential Revision: D3220360
fb-gh-sync-id: 11395dd
fbshipit-source-id: 11395dd
Summary:Local variable created by conditional operator translation is now declared in scope of whole
procedure. Semantically there is no difference, hopefuly backend will not complain about this
change. Also, nullifying that variable is deferred to preanalysis instead of calling it manually
Reviewed By: jvillard
Differential Revision: D3155733
fb-gh-sync-id: 6cec8fc
fbshipit-source-id: 6cec8fc
Summary: For performance critical sections of the code, this checker detects memory allocations or calls to methods annotated as expensive. However, such cases of memory allocations or expensive calls are acceptable is occuring in rare cases. This diff adds supports for the "unlikely" branch prediction method and does not track expensive calls in unlikely branches.
Reviewed By: sblackshear
Differential Revision: D3193473
fb-gh-sync-id: ea87e49
fbshipit-source-id: ea87e49
Summary:BinaryConditionalOperator should evaluate condition expression once, but we used to evaluate it twice.
Fix translation to account for it.
Reviewed By: dulmarod
Differential Revision: D3179803
fb-gh-sync-id: a801a7e
fbshipit-source-id: a801a7e
Summary:This diff translate cpp lambdas. For the moment it does not take care of
captured variables. Captured variables will come in the next diff.
Reviewed By: dulmarod
Differential Revision: D3114790
fb-gh-sync-id: bf36450
fbshipit-source-id: bf36450
Summary:public
When a conditional is the last instruction, there will be a join node leading directly to the exit node.
Some instructions, such as nullification of dead variables, and abstraction, are added to the control flow graph automatically. But, join nodes cannot contain instructions. So when a procedure ends with a conditional, there might be no place to store these instructions.
This diff adds one extra node between the join and the exit node in that situation.
Reviewed By: jvillard
Differential Revision: D3179056
fb-gh-sync-id: 2b9cd7e
fbshipit-source-id: 2b9cd7e
Summary:public
The code:
DataInputStream in = new DataInputStream(new BufferedInputStream(new FileInputStream(file)));
creates a resource with `FileInputStream()` and wraps it twice as a field of `BufferedInputStream` and then as a field of `DataInputStream`. Then calling:
in.close();
needs to go down the wrappers hierachy: `DataInputStream.close()` -> `FilterInputStream.close()` which then calls `BufferedInputStream.close()` -> `FilterInputStream.close()` -> `FileInputStream.close()`.
Going down the wrapper was not working before because `FilterInputStream.close()` was only going further when the type of field `in` was `FileInputStream` wheras it should also continue when the type of the field is any subtype of `FilterInputStream`, e.g. `DataInputStream` and `BufferedInputStream` like in the test example. This diff fixes this last aspect.
Reviewed By: sblackshear
Differential Revision: D3174822
fb-gh-sync-id: 3adbb7e
fbshipit-source-id: 3adbb7e
Summary:public
Instead of translating code from headers blindly, translate only gets transitively referenced from source code.
It won't translate functions from system headers, but in the future we could do that as well
since most of them aren't used and it shouldn't add much overhead.
For now this functionality is hidden behind --cxx-experimental flag
Reviewed By: dulmarod
Differential Revision: D3163519
fb-gh-sync-id: 0c53b10
fbshipit-source-id: 0c53b10
Summary:public
Instead of using location of init_stmt, use location of variable when translating initialization.
Most of the time it change anything with some exceptions:
// example1 - C/C++/objC
int x = // now: assignment happens in this line
3; // past: assignment happens in this line
// example2: valid in C++11 only
struct X {
int x = 0; // now: one assignment here
int y = 2; // now: one assigmnent here
X() = default; // before: 2 assignments in this line
};
Reviewed By: dulmarod
Differential Revision: D3155870
fb-gh-sync-id: f38c78c
fbshipit-source-id: f38c78c
Summary:public
Add modeling of methods that can raise exceptions when parameters are
nil, and that return nil when passed nil.
Reviewed By: dulmarod
Differential Revision: D3101739
fb-gh-sync-id: 76af5a2
fbshipit-source-id: 76af5a2
Summary:public
Create a model of std::unique_ptr in similar fashion to what was done to std::shared_ptr.
For now, we are modeling it as container of raw pointer (no ownership concept).
This time unique_ptr is not derived from std__unique_ptr (unlike shared_ptr, it was easier to not do that) and so we need to provide implementations for all non-member functions per C++ reference:
http://en.cppreference.com/w/cpp/memory/unique_ptr
Reviewed By: dulmarod
Differential Revision: D3048209
fb-gh-sync-id: a9a6455
shipit-source-id: a9a6455
Summary:public
Before this diff, the Java frontend was not adding the definition of the inherited interfaces to the type environment, thus failing to answer questions like "does type X implements Closeable". Infer was therefore missing to detect resource leaks when the resource was indirectly implementing Closeable via an intermediate interface.
Reviewed By: sblackshear
Differential Revision: D3067555
fb-gh-sync-id: 86d0760
shipit-source-id: 86d0760
Summary:public
Implementation of std::move is straightforward and infer understands it without
any problems. To use it, we translate it even though it's coming from system headers.
Reviewed By: jvillard
Differential Revision: D3064019
fb-gh-sync-id: 823ae75
shipit-source-id: 823ae75