27 Commits

Author SHA1 Message Date
Enrico Steffinlongo
11b6cedb8e [analyzer] Improved cmake configuration for Z3
Summary:
Enhanced support for Z3 in the cmake configuration of clang; now it is possible to specify any arbitrary Z3 install prefix (CLANG_ANALYZER_Z3_PREFIX) to cmake with lib (or bin) and include folders. Before the patch only in cmake default locations
were searched (https://cmake.org/cmake/help/v3.4/command/find_path.html).

Specifying any CLANG_ANALYZER_Z3_PREFIX will force also CLANG_ANALYZER_BUILD_Z3 to ON.

Removed also Z3 4.5 version requirement since it was not checked, and now Clang works with Z3 4.7

Reviewers: NoQ, george.karpenkov, mikhail.ramalho

Reviewed By: george.karpenkov

Subscribers: rnkovacs, NoQ, esteffin, george.karpenkov, delcypher, ddcc, mgorny, xazax.hun, szepet, a.sidorin, Szelethus

Tags: #clang

Differential Revision: https://reviews.llvm.org/D50818

llvm-svn: 344464
2018-10-13 19:45:48 +00:00
Enrico Steffinlongo
a72a15a5c7 [analyzer] Small SMT API improvement
Summary: Removed const qualifier from reset method of SMTSolver and Z3Solver objects.

Reviewers: mikhail.ramalho, george.karpenkov, NoQ, ddcc

Reviewed By: NoQ

Subscribers: xazax.hun, szepet, a.sidorin, Szelethus

Differential Revision: https://reviews.llvm.org/D52031

llvm-svn: 344463
2018-10-13 19:42:10 +00:00
Mikhail R. Gadelha
32ce136e80 [analyzer] Improvements to the SMT API
Summary:
Several improvements in preparation for the new backends.

Refactoring:

- Removed duplicated methods `fromBoolean`, `fromAPSInt`, `fromInt` and `fromAPFloat`. The methods `mkBoolean`, `mkBitvector` and `mkFloat` are now used instead.
- The names of the functions that convert BVs to FPs were swapped (`mkSBVtoFP`, `mkUBVtoFP`, `mkFPtoSBV`, `mkFPtoUBV`).
- Added a couple of comments in function calls.

Crosscheck encoding:

- Changed how constraints are encoded in the refutation manager so it doesn't start with (false OR ...). This change introduces one duplicated line (see file `BugReporterVisitors.cpp`, the `SMTConv::getRangeExpr is called twice, so I can remove this change if the duplication is a problem.

Reviewers: george.karpenkov, NoQ

Reviewed By: george.karpenkov

Subscribers: xazax.hun, szepet, a.sidorin, Szelethus

Differential Revision: https://reviews.llvm.org/D52365

llvm-svn: 343581
2018-10-02 12:55:48 +00:00
Mikhail R. Gadelha
766a189dfd [analyzer] Moved all CSA code from the SMT API to a new header, SMTConv.h. NFC.
Summary:
With this patch, the SMT backend is almost completely detached from the CSA.

Unfortunate consequence is that we missed the `ConditionTruthVal` from the CSA and had to use `Optional<bool>`.

The Z3 solver implementation is still in the same file as the `Z3ConstraintManager`, in `lib/StaticAnalyzer/Core/Z3ConstraintManager.cpp` though, but except for that, the SMT API can be moved to anywhere in the codebase.

Reviewers: NoQ, george.karpenkov

Reviewed By: george.karpenkov

Subscribers: xazax.hun, szepet, a.sidorin, Szelethus

Differential Revision: https://reviews.llvm.org/D50772

llvm-svn: 340534
2018-08-23 13:21:31 +00:00
Mikhail R. Gadelha
b0670d349c [analyzer] Templatefy SMTConstraintManager so more generic code can be moved from solver specific implementations. NFC.
Summary:
By making SMTConstraintManager a template and passing the SMT constraint type and expr, we can further move code from the Z3ConstraintManager class to the generic SMT constraint Manager.

Now, each SMT specific constraint manager only needs to implement the method `bool canReasonAbout(SVal X) const`.

Reviewers: NoQ, george.karpenkov

Reviewed By: george.karpenkov

Subscribers: mgorny, xazax.hun, szepet, a.sidorin, Szelethus

Differential Revision: https://reviews.llvm.org/D50770

llvm-svn: 340533
2018-08-23 13:21:00 +00:00
Mikhail R. Gadelha
2420ee9b91 [analyzer] Delete SMTContext. NFC.
Summary: There is no reason to have a base class for a context anymore as each SMT object carries a reference to the specific solver context.

Reviewers: NoQ, george.karpenkov, hiraditya

Reviewed By: hiraditya

Subscribers: hiraditya, xazax.hun, szepet, a.sidorin, Szelethus

Differential Revision: https://reviews.llvm.org/D50768

llvm-svn: 340532
2018-08-23 13:20:18 +00:00
Mikhail R. Gadelha
127093129a [analyzer] Fixed method to get APSInt model
Summary:
This patch replaces the current method of getting an `APSInt` from Z3's model by calling generic API method `getBitvector` instead of `Z3_get_numeral_uint64`.

By calling `getBitvector`, there's no need to handle bitvectors with bit width == 128 separately.

And, as a bonus, clang now compiles correctly with Z3 4.7.1.

Reviewers: NoQ, george.karpenkov

Reviewed By: george.karpenkov

Subscribers: xazax.hun, szepet, a.sidorin

Differential Revision: https://reviews.llvm.org/D49818

llvm-svn: 338020
2018-07-26 11:17:13 +00:00
Mikhail R. Gadelha
3c94b65cb0 [analyzer] Update SMT API documentation and methods
Summary:
Update the documentation of all the classes introduced with the new generic SMT API, most of them were referencing Z3 and how previous operations were being done (like including the context as parameter in a few methods).

Renamed the following methods, so it's clear that the operate on bitvectors:
*`mkSignExt` -> `mkBVSignExt`
*`mkZeroExt` -> `mkBVZeroExt`
*`mkExtract` -> `mkBVExtract`
*`mkConcat` -> `mkBVConcat`

Removed the unecessary methods:
* `getDataExpr`: it was an one line method that called `fromData`
* `mkBitvector(const llvm::APSInt Int)`: it was not being used anywhere

Reviewers: NoQ, george.karpenkov

Reviewed By: george.karpenkov

Subscribers: xazax.hun, szepet, a.sidorin

Differential Revision: https://reviews.llvm.org/D49799

llvm-svn: 337954
2018-07-25 19:34:48 +00:00
Mikhail R. Gadelha
f142c965e4 [analyzer] Use the macro REGISTER_TRAIT_WITH_PROGRAMSTATE in the Z3 backend
Summary:
The macro was manually expanded in the Z3 backend and this patch adds it back.

Adding the expanded code is dangerous as the macro may change in the future and the expanded code might be left outdated.

Reviewers: NoQ, george.karpenkov

Reviewed By: george.karpenkov

Subscribers: xazax.hun, szepet, a.sidorin

Differential Revision: https://reviews.llvm.org/D49769

llvm-svn: 337923
2018-07-25 12:49:47 +00:00
Mikhail R. Gadelha
5c3d032e70 [analyzer] Removed API used by the Refutation Manager from SMTConstraintManager and replace by proper calls to SMTSolver
Summary:
Third patch in the refactoring series, to decouple the SMT Solver from the Refutation Manager (1st: D49668, 2nd: D49767).

The refutation API in the `SMTConstraintManager` was a hack to allow us to create an SMT solver and verify the constraints; it was conceptually wrong from the start. Now, we don't actually need to use the `SMTConstraintManager` and can create an SMT object directly, add the constraints and check them.

While updating the Falsification visitor, I inlined the two functions that were used to collect the constraints and add them to the solver.

As a result of this patch, we could move the SMT API elsewhere and as it's not really dependent on the CSA anymore. Maybe we can create a new dir (utils/smt) for Z3 and future solvers?

Reviewers: NoQ, george.karpenkov

Reviewed By: george.karpenkov

Subscribers: xazax.hun, szepet, a.sidorin

Differential Revision: https://reviews.llvm.org/D49768

llvm-svn: 337922
2018-07-25 12:49:43 +00:00
Mikhail R. Gadelha
456ecffe11 [analyzer] Moved non solver specific code from Z3ConstraintManager to SMTConstraintManager
Summary:
This patch moves a lot of code from `Z3ConstraintManager` to `SMTConstraintManager`, leaving only the necessary:
* `canReasonAbout` which returns if a Solver can handle a given `SVal` (should be moved to `SMTSolver` in the future).
* `removeDeadBindings`, `assumeExpr` and `print`: methods that need to use `ConstraintZ3Ty`, can probably be moved to `SMTConstraintManager` in the future.

The patch creates a new file, `SMTConstraintManager.cpp` with the moved code. Conceptually, this is move in the right direction and needs further improvements: `SMTConstraintManager` still does a lot of things that are not required by a `ConstraintManager`.

We ought to move the unrelated to `SMTSolver` and remove everything that's not related to a `ConstraintManager`. In particular, we could remove `addRangeConstraints` and `isModelFeasible`, and make the refutation manager create an Z3Solver directly.

Reviewers: NoQ, george.karpenkov

Reviewed By: george.karpenkov

Subscribers: mgorny, xazax.hun, szepet, a.sidorin

Differential Revision: https://reviews.llvm.org/D49668

llvm-svn: 337919
2018-07-25 12:49:29 +00:00
Mikhail R. Gadelha
635378b783 [analyzer] Implemented SMT generic API
Summary:
Created new SMT generic API.

Small changes to `Z3ConstraintManager` because of the new generic objects (`SMTSort` and `SMTExpr`) returned by `SMTSolver`.

Reviewers: george.karpenkov, NoQ

Reviewed By: george.karpenkov

Subscribers: mgorny, xazax.hun, szepet, a.sidorin

Differential Revision: https://reviews.llvm.org/D49495

llvm-svn: 337918
2018-07-25 12:49:23 +00:00
Mikhail R. Gadelha
ca6983b95a [analyzer] Create generic SMT Expr class
Summary:
New base class for all future SMT Exprs.

No major changes except moving `areEquivalent` and `getFloatSemantics` outside of `Z3Expr` to keep the class minimal.

Reviewers: NoQ, george.karpenkov

Reviewed By: george.karpenkov

Subscribers: xazax.hun, szepet, a.sidorin

Differential Revision: https://reviews.llvm.org/D49551

llvm-svn: 337917
2018-07-25 12:49:19 +00:00
Mikhail R. Gadelha
cb9e68dc97 [analyzer] Create generic SMT Sort Class
Summary:
New base class for all future SMT sorts.

The only change is that the class implements methods `isBooleanSort()`, `isBitvectorSort()` and `isFloatSort()` so it doesn't rely on `Z3`'s enum.

Reviewers: NoQ, george.karpenkov

Reviewed By: george.karpenkov

Subscribers: xazax.hun, szepet, a.sidorin

Differential Revision: https://reviews.llvm.org/D49550

llvm-svn: 337916
2018-07-25 12:49:15 +00:00
Mikhail R. Gadelha
19f0761020 [analyzer] Moved static Context to class member
Summary:
Although it is a big patch, the changes are simple:
1. There is one `Z3_Context` now, member of the `SMTConstraintManager` class.
2. `Z3Expr`, `Z3Sort`, `Z3Model` and `Z3Solver` are constructed with a reference to the `Z3_Context` in `SMTConstraintManager`.
3. All static functions are now members of `Z3Solver`, e.g, the `SMTConstraintManager` now calls `Solver.fromBoolean(false)` instead of `Z3Expr::fromBoolean(false)`.

Most of the patch only move stuff around except:
1. New method `Z3Sort MkSort(const QualType &Ty, unsigned BitWidth)`, that creates a sort based on the `QualType` and its width. Used to simplify the `fromData` method.

Unfortunate consequence of this patch:
1. `getInterpretation` was moved from `Z3Model` class to `Z3Solver`, because it needs to create a `Z3Sort` before returning the interpretation. This can be fixed by changing both `toAPFloat` and `toAPSInt` by removing the dependency of `Z3Sort` (it's only used to check which Sort was created and to retrieve the type width).

Reviewers: NoQ, george.karpenkov, ddcc

Reviewed By: george.karpenkov

Subscribers: xazax.hun, szepet, a.sidorin

Differential Revision: https://reviews.llvm.org/D49236

llvm-svn: 337915
2018-07-25 12:49:11 +00:00
Mikhail R. Gadelha
0b2aa685a6 [analyzer] Create generic SMT Context class
Summary:
This patch creates `SMTContext` which will wrap a specific SMT context, through `SMTSolverContext`.

The templated `SMTSolverContext` class it's a simple wrapper around a SMT specific context (currently only used in the Z3 backend), while `Z3Context` inherits `SMTSolverContext<Z3_context>` and implements solver specific operations like initialization and destruction of the context.

This separation was done because:

1. We might want to keep one single context, shared across different `SMTConstraintManager`s. It can be achieved by constructing a `SMTContext`, through a function like `CreateSMTContext(Z3)`, `CreateSMTContext(BOOLECTOR)`, etc. The rest of the CSA only need to know about `SMTContext`, so maybe it's a good idea moving `SMTSolverContext` to a separate header in the future.

2. Any generic SMT operation will only require one `SMTSolverContext`object, which can access the specific context by calling `getContext()`.

Reviewers: NoQ, george.karpenkov

Reviewed By: george.karpenkov

Subscribers: xazax.hun, szepet, a.sidorin

Differential Revision: https://reviews.llvm.org/D49233

llvm-svn: 337914
2018-07-25 12:49:07 +00:00
Mikhail R. Gadelha
81943b805b [analyzer] Fix Z3 backend after D48205
Summary:
An assertion was added in D48205 to catch places where a `nonloc::SymbolVal` was wrapping a `loc` object.

This patch fixes that in the Z3 backend by making the `SValBuilder` object accessible from inherited instances of `SimpleConstraintManager` and calling `SVB.makeSymbolVal(foo)` instead of `nonloc::SymbolVal(foo)`.

Reviewers: NoQ, george.karpenkov

Reviewed By: NoQ

Subscribers: xazax.hun, szepet, a.sidorin

Differential Revision: https://reviews.llvm.org/D49430

llvm-svn: 337304
2018-07-17 17:40:34 +00:00
Mikhail R. Gadelha
07f6e8e3a5 [analyzer] Fix the Z3 backend always generating unsigned APSInt
Summary:
In `toAPSInt`, the Z3 backend was not checking the variable `Int`'s type and was always generating unsigned `APSInt`s.

This was found by accident when I removed:
```
    llvm::APSInt ConvertedLHS, ConvertedRHS;
    QualType LTy, RTy;
    std::tie(ConvertedLHS, LTy) = fixAPSInt(*LHS);
    std::tie(ConvertedRHS, RTy) = fixAPSInt(*RHS);
-    doIntTypePromotion<llvm::APSInt, Z3ConstraintManager::castAPSInt>(
-        ConvertedLHS, LTy, ConvertedRHS, RTy);
    return BVF.evalAPSInt(BSE->getOpcode(), ConvertedLHS, ConvertedRHS);
```

And the `BasicValueFactory` started to complain about different `signedness`.

Reviewers: george.karpenkov, NoQ, ddcc

Reviewed By: ddcc

Subscribers: xazax.hun, szepet, a.sidorin

Differential Revision: https://reviews.llvm.org/D49305

llvm-svn: 337169
2018-07-16 13:32:22 +00:00
Mikhail R. Gadelha
53ac1a2ed4 [analyzer] Fix wrong comparison generation of the ranges generated by the refutation manager
The refutation manager is removing a true bug from the test in this patch.

The problem is that the following constraint:
```
(conj_$1{struct o *}) - (reg_$3<int * r>): [-9223372036854775808, 0]
```
is encoded as:
```
(and (bvuge (bvsub $1 $3) #x8000000000000000)
     (bvule (bvsub $1 $3) #x0000000000000000))
```
The issue is that unsigned comparisons (bvuge and bvule) are being generated instead of signed comparisons (bvsge and bvsle).

When generating the expressions:
```
(conj_$1{p *}) - (reg_$3<int * r>) >= -9223372036854775808
```
and
```
(conj_$1{p *}) - (reg_$3<int * r>) <= 0
```
both -9223372036854775808 and 0 are casted to pointer type and `LTy->isSignedIntegerOrEnumerationType()` in `Z3ConstraintManager::getZ3BinExpr` only checks if the type is signed, not if it's a pointer.

Reviewers: NoQ, george.karpenkov, ddcc

Subscribers: rnkovacs, NoQ, george.karpenkov, ddcc, xazax.hun, szepet, a.sidorin

Differential Revision: https://reviews.llvm.org/D48324

llvm-svn: 335926
2018-06-28 21:26:52 +00:00
Mikhail R. Gadelha
bd1077e2bc [analyzer] Optimize constraint generation when the range is a concrete value
Summary:
If a constraint is something like:
```
$0 = [1,1]
```
it'll now be created as:
```
assert($0 == 1)
```
instead of:
```
assert($0 >= 1 && $0 <= 1)
```

In general, ~3% speedup when solving per query in my machine. Biggest improvement was when verifying sqlite3, total time went down from 3000s to 2200s.

I couldn't create a test for this as there is no way to dump the formula yet. D48221 adds a method to dump the formula but there is no way to do it from the command line.

Also, a test that prints the formula will most likely fail in the future, as different solvers print the formula in different formats.

Reviewers: NoQ, george.karpenkov, ddcc

Reviewed By: george.karpenkov

Subscribers: xazax.hun, szepet, a.sidorin

Differential Revision: https://reviews.llvm.org/D48227

llvm-svn: 335116
2018-06-20 11:42:12 +00:00
Mikhail R. Gadelha
e7f703804d [analyzer] Add method to the generic SMT API to dump the SMT formula
Summary:
New method dump the SMT formula and the Z3 implementation.

There is no test because I only used it for debugging.

However, if requested, I can add an option to the static analyzer to dump the formula (whole program? per path?), maybe something like the trimmed graph but for SMT formulas.

Reviewers: NoQ, george.karpenkov, ddcc

Reviewed By: george.karpenkov

Subscribers: xazax.hun, szepet, a.sidorin

Differential Revision: https://reviews.llvm.org/D48221

llvm-svn: 334891
2018-06-16 14:36:17 +00:00
Vlad Tsyrklevich
6f8f15fa72 [Analyzer] Fix Z3ConstraintManager crash (PR37646)
Summary:
Fix another Z3ConstraintManager crash, use fixAPSInt() to extend a
boolean APSInt.

Reviewers: george.karpenkov, NoQ, ddcc

Reviewed By: george.karpenkov

Subscribers: xazax.hun, szepet, a.sidorin, cfe-commits

Differential Revision: https://reviews.llvm.org/D47617

llvm-svn: 334065
2018-06-06 06:09:02 +00:00
Mikhail R. Gadelha
735d8ea0d4 Created a tiny SMT interface and make Z3ConstraintManager implement it
Summary:
This patch implements a simple SMTConstraintManager API, and requires the implementation of two methods for now: `addRangeConstraints` and `isModelFeasible`.

Update Z3ConstraintManager to inherit it and implement required methods.

I also moved the method to dump the SMT formula from D45517 to this patch.

This patch was created based on the reviews from D47640.

Reviewers: george.karpenkov, NoQ, ddcc, dcoughlin

Reviewed By: george.karpenkov

Differential Revision: https://reviews.llvm.org/D47689

llvm-svn: 333899
2018-06-04 14:25:58 +00:00
Dominic Chen
cd81614e8b [analyzer] fix bug with 1-bit APSInt types in Z3ConstraintManager
Summary: Clang does not have a corresponding QualType for a 1-bit APSInt, so use the BoolTy and extend the APSInt. Split from D35450. Fixes PR37622.

Reviewers: george.karpenkov, NoQ

Subscribers: mikhail.ramalho, xazax.hun, szepet, rnkovacs, cfe-commits, a.sidorin

Differential Revision: https://reviews.llvm.org/D47603

llvm-svn: 333704
2018-05-31 22:23:07 +00:00
Dominic Chen
c0402c6916 Revert "[analyzer] Support generating and reasoning over more symbolic constraint types"
Assertion `Loc::isLocType(SSE->getLHS()->getType())' failed in Analysis/PR3991.m

This reverts commit e469ff2759275e67f9072b3d67fac90f647c0fe6.

llvm-svn: 307853
2017-07-12 21:43:42 +00:00
Dominic Chen
35610d21b2 [analyzer] Support generating and reasoning over more symbolic constraint types
Summary: Generate more IntSymExpr constraints, perform SVal simplification for IntSymExpr and SymbolCast constraints, and create fully symbolic SymExprs

Reviewers: zaks.anna, dcoughlin, NoQ, xazax.hun

Subscribers: mgorny, cfe-commits

Differential Revision: https://reviews.llvm.org/D28953

llvm-svn: 307833
2017-07-12 19:37:57 +00:00
Dominic Chen
08f943c563 [analyzer] Add new Z3 constraint manager backend
Summary: Implement new Z3 constraint manager backend.

Reviewers: zaks.anna, dcoughlin, NoQ, xazax.hun

Subscribers: mgorny, cfe-commits

Differential Revision: https://reviews.llvm.org/D28952

llvm-svn: 299463
2017-04-04 19:52:25 +00:00