dcoughlin added a comment.

Thanks for updating the tests to be able to run both the z3 and 
range-constraint managers! I think this will make it much easier to ensure the 
z3-backed manager continues to work as as expected moving forward. I suggested 
an alternative approach inline to running the tests under both managers, which 
you may wish to consider.

In https://reviews.llvm.org/D28952#669963, @ddcc wrote:

> I added support for a callback field in lit's configuration (see 
> https://reviews.llvm.org/D29684), which is used to execute each testcase for 
> each supported constraint solver backends at runtime. I believe this resolves 
> all remaining issues, except for the remaining two testcase failures:
>
> 1. The testcase Analysis/reference.cpp currently fails, because the 
> RangeConstraintManager has an internal optimization that assumes references 
> are known to be non-zero (see RangeConstraintManager.cpp:422). This 
> optimization is probably in the wrong place, and should be moved into the 
> analyzer and out of the constraint solver. Unless anyone objects, I plan to 
> modify this testcase so that this result is fine for the z3 solver backend.


This sounds reasonable to me.

> 1. The testcase Analysis/ptr-arith.c currently fails, because handling of 
> ptrdiff_t is somewhat tricky. This constraint manager interface maps 
> ptrdiff_t to a signed bitvector in Z3, and pointers to unsigned bitvectors in 
> Z3. However, since this testcase compares the pointer values both directly 
> and indirectly via ptrdiff_t, if a < b is true using a signed comparison, the 
> same is not necessarily true using an unsigned comparison. Likewise, unless 
> anyone objects, I plan to whitelist this result for the z3 solver backend.

I think in both cases whitelisting is the right thing to do -- just provide a 
comment in the test explaining why. If you have a sense of the right way to fix 
the problem, please add a // FIXME: in the test with a short description.

There are some minor comments inline. Also: It is important to make sure the 
build still works and the tests still pass even both when Z3 is not present and 
when it is not enabled.



================
Comment at: CMakeLists.txt:371
 
+option(CLANG_BUILD_Z3
+  "Build the static analyzer with the Z3 constraint manager." OFF)
----------------
I think it would be good to change the name of this setting to have the prefix 
"CLANG_ANALYZER_...". This will help make it clear in, for example, the ccmake 
interface, that the option is only relevant to the analyzer.


================
Comment at: lib/StaticAnalyzer/Core/CMakeLists.txt:62
+  ${Z3_LINK_FILES}
   )
----------------
This needs something like:
```
if(CLANG_BUILD_Z3 AND CLANG_HAVE_Z3)
  target_include_directories(clangStaticAnalyzerCore SYSTEM
  PRIVATE
  ${Z3_INCLUDE_DIR}
  )
endif()
```
so that the analyzer core can find the Z3 headers when they are installed 
outside of the usual system include paths.


================
Comment at: lib/StaticAnalyzer/Core/Z3ConstraintManager.cpp:17
+
+#if defined(CLANG_BUILD_Z3) && defined(CLANG_HAVE_Z3)
+
----------------
Is it possible to expose only one Z3-related definition here? Does the C++ need 
to understand the distinction between CLANG_HAVE_Z3 and CLANG_BUILD_Z3?

Could the CMake expose one master build setting that is true when other two are 
both true?


================
Comment at: lib/StaticAnalyzer/Core/Z3ConstraintManager.cpp:21
+
+using namespace clang;
+using namespace ento;
----------------
These 'using' declarations need to be moved outside the #if -- otherwise there 
is a compile error at the definition of CreateZ3ConstraintManager() when 
building without Z3.


================
Comment at: test/Analysis/lit.local.cfg:2
+import lit.TestRunner
+
+def callback(test, cmd):
----------------
Here is a suggestion that would avoid needing to block changes to 'lit' itself.

lit allows you to create different a different Test subclass in each test 
directory. You could create a custom subclass just for analyzer tests (we 
already do this for unit tests):

```
class AnalyzerTest(lit.formats.ShTest, object):

    def execute(self, test, litConfig):
        result = self.executeWithAnalyzeSubstitution(test, litConfig, 
'-analyzer-constraints=range')

        if result.code == lit.Test.FAIL:
            return result
      
        if test.config.build_z3 == 'ON' and test.config.have_z3 == '1':
            result = self.executeWithAnalyzeSubstitution(test, litConfig, 
'-analyzer-constraints=z3 -DANALYZER_CM_Z3')

        return result

    def executeWithAnalyzeSubstitution(self, test, litConfig, substitution):
        saved_substitutions = list(test.config.substitutions)
        test.config.substitutions.append(('%analyze', substitution))
        result = lit.TestRunner.executeShTest(test, litConfig, 
self.execute_external)
        test.config.substitutions = saved_substitutions

        return result


config.test_format = AnalyzerTest(config.test_format.execute_external)
```

Saving and mutating the substitutions is kind of janky, but it would avoid 
blocking this commit on an expanded lit interface.


https://reviews.llvm.org/D28952



_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to