Bug 1479503: Check infer in ./mach static-analysis autotest. draft
authorRobert Bartlensky <rbartlensky@mozilla.com>
Thu, 09 Aug 2018 15:03:12 +0100
changeset 829937 3cb1dfa2a087a4384dc7c1ad7974369fd672c30c
parent 829936 b84213ec5a4d922b4908fdfc689d47593efc3c74
push id118801
push userbmo:rbartlensky@mozilla.com
push dateFri, 17 Aug 2018 12:50:32 +0000
bugs1479503
milestone63.0a1
Bug 1479503: Check infer in ./mach static-analysis autotest. MozReview-Commit-ID: JxdoprwvXRY
.flake8
.hgignore
mobile/android/geckoview/build.gradle
moz.configure
python/mozbuild/mozbuild/mach_commands.py
taskcluster/ci/docker-image/kind.yml
taskcluster/ci/static-analysis-autotest/kind.yml
taskcluster/ci/toolchain/linux.yml
taskcluster/docker/infer-build/Dockerfile
taskcluster/docker/static-analysis-build/Dockerfile
taskcluster/scripts/misc/gradle-sa-autotest-dependencies.sh
taskcluster/scripts/misc/gradle-sa-autotest-dependencies/after.sh
testing/mozharness/configs/builds/releng_sub_linux_configs/64_sa_autotest.py
testing/mozharness/mozharness/base/script.py
testing/mozharness/mozharness/mozilla/building/buildbase.py
tools/infer/config.yaml
tools/infer/test/autotest/build.gradle
tools/infer/test/autotest/src/main/java/Biabduction.java
tools/infer/test/autotest/src/main/java/Biabduction.json
tools/infer/test/autotest/src/main/java/Checkers.java
tools/infer/test/autotest/src/main/java/Checkers.json
tools/infer/test/autotest/src/main/java/Eradicate.java
tools/infer/test/autotest/src/main/java/Racerd.java
tools/infer/test/autotest/src/main/java/Racerd.json
tools/infer/test/autotest/src/main/java/Starvation.java
tools/infer/test/autotest/src/main/java/Starvation.json
tools/infer/test/config/mozconfigs/common.conf
tools/infer/test/config/mozconfigs/gradle.conf
tools/infer/test/gradle.properties
tools/infer/test/gradle/wrapper/gradle-wrapper.jar
tools/infer/test/gradle/wrapper/gradle-wrapper.properties
tools/infer/test/gradlew
tools/infer/test/gradlew.bat
tools/infer/test/moz.configure
tools/infer/test/settings.gradle
--- a/.flake8
+++ b/.flake8
@@ -17,8 +17,9 @@ exclude =
     js/*.configure,
     memory/moz.configure,
     mobile/android/*.configure,
     node_modules,
     security/nss/,
     testing/mochitest/pywebsocket,
     tools/lint/test/files,
     build/build-infer/build-infer.py,
+    tools/infer/test/*.configure,
--- a/.hgignore
+++ b/.hgignore
@@ -29,16 +29,17 @@
 ^\.clang_complete
 ^\.?machrc$
 
 # Empty marker file that's generated when we check out NSS
 ^security/manager/\.nss\.checkout$
 
 # Build directories
 ^obj
+^tools/infer/test/autotest/build/
 
 # gecko.log is generated by various test harnesses
 ^gecko\.log
 
 # Build directories for js shell
 _DBG\.OBJ/
 _OPT\.OBJ/
 ^js/src/.*-obj/
@@ -67,16 +68,17 @@
 # Ignore the files and directory that JetBrains IDEs create.
 \.idea/
 \.iml$
 # Android Monitor in Android Studio creates a captures/ directory.
 ^captures/
 
 # Gradle cache.
 ^.gradle/
+^tools/infer/test/.gradle/
 
 # Local Gradle configuration properties.
 ^local.properties$
 
 # Python stuff installed at build time.
 ^third_party/python/psutil/.*\.so
 ^third_party/python/psutil/.*\.pyd
 ^third_party/python/psutil/build/
--- a/mobile/android/geckoview/build.gradle
+++ b/mobile/android/geckoview/build.gradle
@@ -1,8 +1,10 @@
+
+
 buildDir "${topobjdir}/gradle/build/mobile/android/geckoview"
 
 apply plugin: 'com.android.library'
 apply plugin: 'kotlin-android'
 
 apply from: "${topsrcdir}/mobile/android/gradle/product_flavors.gradle"
 
 // The SDK binding generation tasks depend on the JAR creation task of the
--- a/moz.configure
+++ b/moz.configure
@@ -561,16 +561,18 @@ def nsis_flags(host):
     if host.kernel != 'WINNT':
         return '-nocd'
     return ''
 
 set_config('MAKENSISU_FLAGS', nsis_flags)
 
 check_prog('7Z', ('7z', '7za'), allow_missing=True, when=target_is_windows)
 
+include('tools/infer/test/moz.configure')
+
 # Fallthrough to autoconf-based configure
 include('build/moz.configure/old.configure')
 
 @depends(check_build_environment, build_project)
 @imports('__sandbox__')
 @imports('glob')
 def config_status_deps(build_env, build_project):
 
--- a/python/mozbuild/mozbuild/mach_commands.py
+++ b/python/mozbuild/mozbuild/mach_commands.py
@@ -1664,24 +1664,18 @@ class StaticAnalysis(MachCommandBase):
             StaticAnalysisFooter,
             StaticAnalysisOutputManager,
         )
 
         self._set_log_level(verbose)
         self.log_manager.enable_all_structured_loggers()
 
         rc = self._build_compile_db(verbose=verbose)
-        if rc != 0:
-            return rc
-
-        rc = self._build_export(jobs=jobs, verbose=verbose)
-        if rc != 0:
-            return rc
-
-        rc = self._get_clang_tools(verbose=verbose)
+        rc = rc or self._build_export(jobs=jobs, verbose=verbose)
+        rc = rc or self._get_clang_tools(verbose=verbose)
         if rc != 0:
             return rc
 
         compile_db = json.loads(open(self._compile_db, 'r').read())
         total = 0
         import re
         name_re = re.compile('(' + ')|('.join(source) + ')')
         for f in compile_db:
@@ -1759,31 +1753,25 @@ class StaticAnalysis(MachCommandBase):
                      'This command is only available for linux64!')
             return rc
         # which checkers to use, and which folders to exclude
         all_checkers, third_party_path = self._get_infer_config()
         checkers, excludes = self._get_infer_args(
             checks=checks or all_checkers,
             third_party_path=third_party_path
         )
-        gradlew = mozpath.join(self.topsrcdir, 'gradlew')
+        rc = rc or self._gradle(['clean'])  # clean so that we can recompile
         # infer capture command
-        capture_cmd = [self._infer_path, 'capture'] + excludes + \
-            ['--', gradlew, task]
+        capture_cmd = [self._infer_path, 'capture'] + excludes + ['--']
+        rc = rc or self._gradle([task], infer_args=capture_cmd, verbose=verbose)
         tmp_file, args = self._get_infer_source_args(java_sources)
         # infer analyze command
         analysis_cmd = [self._infer_path, 'analyze', '--keep-going'] +  \
             checkers + args
-        # capture, then analyze the sources
-        for args in [[gradlew, 'clean'], capture_cmd, analysis_cmd]:
-            rc = self.run_process(args=args, cwd=self.topsrcdir,
-                                  pass_thru=True)
-            # if a command fails, break and close the tmp file before returning
-            if rc != 0:
-                break
+        rc = rc or self.run_process(args=analysis_cmd, cwd=self.topsrcdir, pass_thru=True)
         if tmp_file:
             tmp_file.close()
         return rc
 
     def _get_java_files(self, sources):
         java_sources = []
         for i in sources:
             f = mozpath.join(self.topsrcdir, i)
@@ -1860,88 +1848,108 @@ class StaticAnalysis(MachCommandBase):
         if fix:
             common_args += '-fix'
 
         return [
             self.virtualenv_manager.python_path, self._run_clang_tidy_path, '-j',
             str(jobs), '-p', self._compilation_commands_path
         ] + common_args + sources
 
+    @StaticAnalysisSubCommand('static-analysis', 'autotest-deps',
+                              'Command run in automation.')
+    def autotest_deps(self, verbose=False):
+        # We don't want to gate producing dependency archives on clean
+        # lint or checkstyle, particularly because toolchain versions
+        # can change the outputs for those processes.
+        return self._gradle(self.substs['GRADLE_INFER_AUTOTEST_TASKS'] +
+                            ["--continue"], verbose=True, autotest=True)
+
+    def _gradle(self, args, infer_args=None, verbose=False, autotest=False,
+                suppress_output=True):
+        from mozbuild.shellutil import (
+            split as shell_split,
+        )
+        infer_args = infer_args or []
+        gradle_flags = self.substs.get('GRADLE_FLAGS', '') or \
+            os.environ.get('GRADLE_FLAGS', '')
+        gradle_flags = shell_split(gradle_flags) + ['--console=plain']
+        java_home = os.path.dirname(os.path.dirname(self.substs['JAVA']))
+        if autotest:
+            gradle = self.substs['GRADLE_SA_AUTOTEST']
+            cwd = mozpath.join(self.topsrcdir, 'tools', 'infer', 'test')
+        else:
+            gradle = self.substs['GRADLE']
+            cwd = self.topsrcdir
+        extra_env = {
+            'GRADLE_OPTS': '-Dfile.encoding=utf-8',
+            'JAVA_HOME': java_home,
+            'JAVA_TOOL_OPTIONS': '-Dfile.encoding=utf-8',
+        }
+        if suppress_output:
+            devnull = open(os.devnull, 'w')
+            return subprocess.call(
+                infer_args + [gradle] + gradle_flags + args,
+                env=dict(os.environ, **extra_env),
+                cwd=cwd, stdout=devnull, stderr=subprocess.STDOUT, close_fds=True)
+        else:
+            return self.run_process(
+                infer_args + [gradle] + gradle_flags + args,
+                append_env=extra_env,
+                pass_thru=True,  # Allow user to run gradle interactively.
+                ensure_exit_code=False,  # Don't throw on non-zero exit code.
+                cwd=cwd)
+
     @StaticAnalysisSubCommand('static-analysis', 'autotest',
                               'Run the auto-test suite in order to determine that'
                               ' the analysis did not regress.')
     @CommandArgument('--dump-results', '-d', default=False, action='store_true',
                      help='Generate the baseline for the regression test. Based on'
                      ' this baseline we will test future results.')
     @CommandArgument('--intree-tool', '-i', default=False, action='store_true',
                      help='Use a pre-aquired in-tree clang-tidy package.')
     @CommandArgument('checker_names', nargs='*', default=[],
                      help='Checkers that are going to be auto-tested.')
     def autotest(self, verbose=False, dump_results=False, intree_tool=False, checker_names=[]):
         # If 'dump_results' is True than we just want to generate the issues files for each
         # checker in particulat and thus 'force_download' becomes 'False' since we want to
         # do this on a local trusted clang-tidy package.
         self._set_log_level(verbose)
         self._dump_results = dump_results
-
-        force_download = True
-
-        if self._dump_results:
-            force_download = False
+        force_download = False  # not self._dump_results
 
         # Function return codes
         self.TOOLS_SUCCESS = 0
         self.TOOLS_FAILED_DOWNLOAD = 1
         self.TOOLS_UNSUPORTED_PLATFORM = 2
         self.TOOLS_CHECKER_NO_TEST_FILE = 3
         self.TOOLS_CHECKER_RETURNED_NO_ISSUES = 4
         self.TOOLS_CHECKER_RESULT_FILE_NOT_FOUND = 5
         self.TOOLS_CHECKER_DIFF_FAILED = 6
         self.TOOLS_CHECKER_NOT_FOUND = 7
-
-        # Configure the tree or download clang-tidy package, depending on the option that we choose
-        if intree_tool:
-            _, config, _ = self._get_config_environment()
-            clang_tools_path = self.topsrcdir
-            self._clang_tidy_path = mozpath.join(
-                clang_tools_path, "clang", "bin",
-                "clang-tidy" + config.substs.get('BIN_SUFFIX', ''))
-            self._clang_format_path = mozpath.join(
-                clang_tools_path, "clang", "bin",
-                "clang-format" + config.substs.get('BIN_SUFFIX', ''))
-            self._clang_apply_replacements = mozpath.join(
-                clang_tools_path, "clang", "bin",
-                "clang-apply-replacements" + config.substs.get('BIN_SUFFIX', ''))
-            self._run_clang_tidy_path = mozpath.join(clang_tools_path, "clang", "share",
-                                                     "clang", "run-clang-tidy.py")
-            self._clang_format_diff = mozpath.join(clang_tools_path, "clang", "share",
-                                                   "clang", "clang-format-diff.py")
-
-            # Ensure that clang-tidy is present
-            rc = not os.path.exists(self._clang_tidy_path)
-        else:
-            rc = self._get_clang_tools(force=force_download, verbose=verbose)
-
+        self.TOOLS_GRADLE_FAILED = 8
+
+        rc = self._get_clang_tools(force=force_download, verbose=verbose, intree_tool=intree_tool)
         if rc != 0:
             self.log(logging.ERROR, 'ERROR: static-analysis', {},
                      'clang-tidy unable to locate package.')
             return self.TOOLS_FAILED_DOWNLOAD
 
         self._clang_tidy_base_path = mozpath.join(self.topsrcdir, "tools", "clang-tidy")
 
         # For each checker run it
         f = open(mozpath.join(self._clang_tidy_base_path, "config.yaml"))
         import yaml
         config = yaml.safe_load(f)
         platform, _ = self.platform
 
         if platform not in config['platforms']:
             self.log(logging.ERROR, 'static-analysis', {},
-                     "RUNNING: clang-tidy autotest for platform {} not supported.".format(platform))
-            return TOOLS_UNSUPORTED_PLATFORM
+                     "RUNNING: clang-tidy autotest for platform {} not supported."
+                     .format(platform))
+            return self.TOOLS_UNSUPORTED_PLATFORM
 
         import concurrent.futures
         import multiprocessing
         import shutil
 
         max_workers = multiprocessing.cpu_count()
 
         self.log(logging.INFO, 'static-analysis', {},
@@ -1971,42 +1979,152 @@ class StaticAnalysis(MachCommandBase):
                 futures.append(executor.submit(self._verify_checker, item))
 
             for future in concurrent.futures.as_completed(futures):
                 ret_val = future.result()
                 if ret_val != self.TOOLS_SUCCESS:
                     # Also delete the tmp folder
                     shutil.rmtree(self._compilation_commands_path)
                     return ret_val
-
         self.log(logging.INFO, 'static-analysis', {}, "SUCCESS: clang-tidy all tests passed.")
         # Also delete the tmp folder
         shutil.rmtree(self._compilation_commands_path)
-        return self.TOOLS_SUCCESS
+        return self._autotest_infer(intree_tool, force_download, verbose)
 
     def _create_temp_compilation_db(self, config):
         directory = tempfile.mkdtemp(prefix='cc')
         with open(mozpath.join(directory, "compile_commands.json"), "wb") as file_handler:
             compile_commands = []
             director = mozpath.join(self.topsrcdir, 'tools', 'clang-tidy', 'test')
             for item in config['clang_checkers']:
                 if item['name'] in ['-*', 'mozilla-*']:
                     continue
                 file = item['name'] + '.cpp'
                 element = {}
                 element["directory"] = director
-                element["command"] = 'cpp '+ file
+                element["command"] = 'cpp ' + file
                 element["file"] = mozpath.join(director, file)
                 compile_commands.append(element)
 
             json.dump(compile_commands, file_handler)
             file_handler.flush()
 
             return directory
 
+    def _autotest_infer(self, intree_tool, force_download, verbose):
+        # infer is not available on other platforms, but autotest should work even without
+        # it being installed
+        if self.platform[0] == 'linux64':
+            rc = self._get_infer(force=force_download, verbose=verbose, intree_tool=intree_tool)
+            if rc != 0:
+                self.log(logging.ERROR, 'ERROR: static-analysis', {},
+                         'infer unable to locate package.')
+                return self.TOOLS_FAILED_DOWNLOAD
+            self.__infer_tool = mozpath.join(self.topsrcdir, 'tools', 'infer')
+            self.__infer_test_folder = mozpath.join(self.__infer_tool, 'test')
+
+            import concurrent.futures
+            import multiprocessing
+            max_workers = multiprocessing.cpu_count()
+            self.log(logging.INFO, 'static-analysis', {},
+                     "RUNNING: infer autotest for platform {0} with {1} workers.".format(
+                         self.platform[0], max_workers))
+            # clean previous autotest if it exists
+            rc = self._gradle(['autotest:clean'], autotest=True)
+            if rc != 0:
+                return rc
+            import yaml
+            with open(mozpath.join(self.__infer_tool, 'config.yaml')) as f:
+                config = yaml.safe_load(f)
+            with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor:
+                futures = []
+                for item in config['infer_checkers']:
+                    if item['publish']:
+                        futures.append(executor.submit(self._verify_infer_checker, item))
+                # this is always included in check-java, but not in config.yaml
+                futures.append(executor.submit(self._verify_infer_checker,
+                                               {'name': 'checkers'}))
+                for future in concurrent.futures.as_completed(futures):
+                    ret_val = future.result()
+                    if ret_val != self.TOOLS_SUCCESS:
+                        return ret_val
+            self.log(logging.INFO, 'static-analysis', {}, "SUCCESS: infer all tests passed.")
+        return self.TOOLS_SUCCESS
+
+    def _verify_infer_checker(self, item):
+        def to_camelcase(str):
+            return ''.join([s.capitalize() for s in str.split('-')])
+        check = item['name']
+        test_file_path = mozpath.join(self.__infer_tool, 'test', 'autotest', 'src',
+                                      'main', 'java', to_camelcase(check))
+        test_file_path_java = test_file_path + '.java'
+        test_file_path_json = test_file_path + '.json'
+        self.log(logging.INFO, 'static-analysis', {}, "RUNNING: infer check {}.".format(check))
+        # Verify if the test file exists for this checker
+        if not os.path.exists(test_file_path_java):
+            self.log(logging.ERROR, 'static-analysis', {},
+                     "ERROR: infer check {} doesn't have a test file.".format(check))
+            return self.TOOLS_CHECKER_NO_TEST_FILE
+        # run infer on a particular test file
+        out_folder = mozpath.join(self.__infer_test_folder, 'test-infer-{}'.format(check))
+        if check == 'checkers':
+            check_arg = ['-a', 'checkers']
+        else:
+            check_arg = ['--{}-only'.format(check)]
+        infer_args = [self._infer_path, 'run'] + check_arg + ['-o', out_folder, '--']
+        gradle_args = ['autotest:compileInferTest{}'.format(to_camelcase(check))]
+        rc = self._gradle(gradle_args, infer_args=infer_args, autotest=True)
+        if rc != 0:
+            self.log(logging.ERROR, 'static-analysis', {},
+                     "ERROR: infer failed to execute gradle {}.".format(gradle_args))
+            return self.TOOLS_GRADLE_FAILED
+        import json
+        issues = json.load(open(mozpath.join(out_folder, 'report.json')))
+        # remove folder that infer creates because the issues are loaded into memory
+        import shutil
+        shutil.rmtree(out_folder)
+        # Verify to see if we got any issues, if not raise exception
+        if not issues:
+            self.log(
+                logging.ERROR, 'static-analysis', {},
+                "ERROR: infer check {0} did not find any issues in its associated test suite."
+                .format(check)
+            )
+            return self.TOOLS_CHECKER_RETURNED_NO_ISSUES
+        if self._dump_results:
+            self._build_autotest_result(test_file_path_json, issues)
+        else:
+            if not os.path.exists(test_file_path_json):
+                # Result file for test not found maybe regenerate it?
+                self.log(
+                    logging.ERROR, 'static-analysis', {},
+                    "ERROR: infer result file not found for check {0}".format(check)
+                )
+                return self.TOOLS_CHECKER_RESULT_FILE_NOT_FOUND
+            # Read the pre-determined issues
+            baseline_issues = self._get_autotest_stored_issues(test_file_path_json)
+
+            def ordered(obj):
+                if isinstance(obj, dict):
+                    return sorted((k, ordered(v)) for k, v in obj.items())
+                if isinstance(obj, list):
+                    return sorted(ordered(x) for x in obj)
+                return obj
+            # Compare the two lists
+            if ordered(issues) != ordered(baseline_issues):
+                error_str = "ERROR: in check {} Expected: ".format(check)
+                error_str += '\n' + json.dumps(baseline_issues, indent=2)
+                error_str += '\n Got:\n' + json.dumps(issues, indent=2)
+                self.log(logging.ERROR, 'static-analysis', {},
+                         'ERROR: infer autotest for check {} failed, check stdout for more details'
+                         .format(check))
+                print(error_str)
+                return self.TOOLS_CHECKER_DIFF_FAILED
+        return self.TOOLS_SUCCESS
+
     @StaticAnalysisSubCommand('static-analysis', 'install',
                               'Install the static analysis helper tool')
     @CommandArgument('source', nargs='?', type=str,
                      help='Where to fetch a local archive containing the static-analysis and '
                      'format helper tool.'
                           'It will be installed in ~/.mozbuild/clang-tools and ~/.mozbuild/infer.'
                           'Can be omitted, in which case the latest clang-tools and infer '
                           'helper for the platform would be automatically detected and installed.')
@@ -2252,36 +2370,39 @@ class StaticAnalysis(MachCommandBase):
         # Converts all the paths to absolute pathnames
         tmp_path = []
         for f in paths:
             tmp_path.append(os.path.abspath(f))
         return tmp_path
 
     def _get_clang_tools(self, force=False, skip_cache=False,
                          source=None, download_if_needed=True,
-                         verbose=False):
+                         verbose=False, intree_tool=False):
         rc, config, _ = self._get_config_environment()
 
         if rc != 0:
             return rc
 
-        clang_tools_path = mozpath.join(self._mach_context.state_dir, "clang-tools")
+        clang_tools_path = self.topsrcdir if intree_tool else \
+            mozpath.join(self._mach_context.state_dir, "clang-tools")
         self._clang_tidy_path = mozpath.join(clang_tools_path, "clang", "bin",
                                              "clang-tidy" + config.substs.get('BIN_SUFFIX', ''))
         self._clang_format_path = mozpath.join(
             clang_tools_path, "clang", "bin",
             "clang-format" + config.substs.get('BIN_SUFFIX', ''))
         self._clang_apply_replacements = mozpath.join(
             clang_tools_path, "clang", "bin",
             "clang-apply-replacements" + config.substs.get('BIN_SUFFIX', ''))
         self._run_clang_tidy_path = mozpath.join(clang_tools_path, "clang", "share", "clang",
                                                  "run-clang-tidy.py")
         self._clang_format_diff = mozpath.join(clang_tools_path, "clang", "share", "clang",
                                                "clang-format-diff.py")
-
+        if intree_tool:
+            # Ensure that clang-tidy is present
+            return not os.path.exists(self._clang_tidy_path)
         if os.path.exists(self._clang_tidy_path) and \
            os.path.exists(self._clang_format_path) and \
            os.path.exists(self._clang_apply_replacements) and \
            os.path.exists(self._run_clang_tidy_path) and \
            not force:
             return 0
         else:
             if os.path.isdir(clang_tools_path) and download_if_needed:
@@ -2372,25 +2493,27 @@ class StaticAnalysis(MachCommandBase):
                         continue  # empty or comment
                     magics = ['exclude']
                     if pattern.startswith('^'):
                         magics += ['top']
                         pattern = pattern[1:]
                     args += [':({0}){1}'.format(','.join(magics), pattern)]
         return args
 
-    def _get_infer(self, force=False, skip_cache=False,
-                   download_if_needed=True, verbose=False):
+    def _get_infer(self, force=False, skip_cache=False, download_if_needed=True,
+                   verbose=False, intree_tool=False):
         rc, config, _ = self._get_config_environment()
         if rc != 0:
             return rc
-        infer_path = mozpath.join(self._mach_context.state_dir, 'infer')
-        self._infer_path = mozpath.join(infer_path, 'infer', 'bin',
-                                        'infer' +
+        infer_path = self.topsrcdir if intree_tool else \
+            mozpath.join(self._mach_context.state_dir, 'infer')
+        self._infer_path = mozpath.join(infer_path, 'infer', 'bin', 'infer' +
                                         config.substs.get('BIN_SUFFIX', ''))
+        if intree_tool:
+            return not os.path.exists(self._infer_path)
         if os.path.exists(self._infer_path) and not force:
             return 0
         else:
             if os.path.isdir(infer_path) and download_if_needed:
                 # The directory exists, perhaps it's corrupted?  Delete it
                 # and start from scratch.
                 import shutil
                 shutil.rmtree(infer_path)
--- a/taskcluster/ci/docker-image/kind.yml
+++ b/taskcluster/ci/docker-image/kind.yml
@@ -81,19 +81,19 @@ jobs:
       - deb9-mercurial
       - deb9-python-zstandard
   android-build:
     symbol: I(agb)
     parent: debian9-base
   fetch:
     symbol: I(fetch)
     parent: debian9-base
-  infer-build:
-    symbol: I(infer)
-    parent: debian9-base
+  static-analysis-build:
+    symbol: I(static-analysis-build)
+    parent: android-build
   mingw32-build:
     symbol: I(mingw)
     parent: debian9-base
   index-task:
     symbol: I(idx)
   funsize-update-generator:
     symbol: I(pg)
   google-play-strings:
--- a/taskcluster/ci/static-analysis-autotest/kind.yml
+++ b/taskcluster/ci/static-analysis-autotest/kind.yml
@@ -31,26 +31,32 @@ job-defaults:
         kind: build
         tier: 1
 
 jobs:
     linux64-st-autotest/debug:
         description: "Linux64 Debug Static Analysis Autotest"
         index:
             job-name: linux64-st-autotest-debug
+        worker:
+            docker-image: {in-tree: static-analysis-build}
+            env:
+                PERFHERDER_EXTRA_OPTIONS: static-analysis-autotest
+                GRADLE_USER_HOME: "/builds/worker/workspace/build/src/mobile/android/gradle/dotgradle-offline"
+                TOOLTOOL_MANIFEST: "mobile/android/config/tooltool-manifests/android/releng.manifest"
         treeherder:
             platform: linux64/debug
         worker-type: aws-provisioner-v1/gecko-t-linux-large
         run:
             config:
-                - builds/releng_base_firefox.py
-                - builds/releng_sub_linux_configs/64_stat_and_debug.py
+                - builds/releng_sub_linux_configs/64_sa_autotest.py
             tooltool-downloads: public
             keep-artifacts: false
         toolchains:
+            - gradle-sa-autotest-dependencies
             - linux64-clang
             - linux64-clang-tidy
             - linux64-infer
             - linux64-rust
             - linux64-sccache
             - linux64-node
 
     win64-st-autotest/debug:
--- a/taskcluster/ci/toolchain/linux.yml
+++ b/taskcluster/ci/toolchain/linux.yml
@@ -153,17 +153,17 @@ linux64-infer:
         job-name: linux64-infer
     treeherder:
         kind: build
         platform: toolchains/opt
         symbol: TL(infer)
         tier: 1
     worker-type: aws-provisioner-v1/gecko-{level}-b-linux
     worker:
-        docker-image: {in-tree: infer-build}
+        docker-image: {in-tree: static-analysis-build}
         max-run-time: 3600
     run:
         using: toolchain-script
         script: build-infer-linux.sh
         resources:
             - 'build/build-infer/build-infer.py'
             - 'build/build-infer/infer-linux64.json'
         toolchain-artifact: public/build/infer.tar.xz
@@ -451,16 +451,42 @@ linux64-android-gradle-dependencies:
             - 'mobile/android/gradle.configure'
         toolchain-artifact: public/build/android-gradle-dependencies.tar.xz
         toolchain-alias: android-gradle-dependencies
     toolchains:
         # Aliases aren't allowed for toolchains depending on toolchains.
         - linux64-android-sdk-linux-repack
         - linux64-node
 
+linux64-gradle-sa-autotest-dependencies:
+    description: "Gradle dependencies toolchain for static-analysis autotest"
+    treeherder:
+        kind: build
+        platform: toolchains/opt
+        symbol: TL(gradle-sa-dependencies)
+        tier: 1
+    worker-type: aws-provisioner-v1/gecko-{level}-b-linux
+    worker:
+        docker-image: {in-tree: android-build}
+        env:
+            GRADLE_USER_HOME: "/builds/worker/workspace/build/src/mobile/android/gradle/dotgradle-online"
+        max-run-time: 1800
+    run:
+        using: toolchain-script
+        script: gradle-sa-autotest-dependencies.sh
+        sparse-profile: null
+        resources:
+            - 'taskcluster/scripts/misc/tooltool-download.sh'
+            - 'taskcluster/scripts/misc/gradle-sa-autotest-dependencies/**'
+            - 'tools/infer/test/*.gradle'
+            - 'tools/infer/test/autotest/*.gradle'
+            - 'tools/infer/test/moz.configure'
+        toolchain-artifact: public/build/gradle-sa-autotest-dependencies.tar.xz
+        toolchain-alias: gradle-sa-autotest-dependencies
+
 linux64-rust-1.28:
     description: "rust repack"
     treeherder:
         kind: build
         platform: toolchains/opt
         symbol: TL(rust)
         tier: 1
     worker-type: aws-provisioner-v1/gecko-{level}-b-linux
rename from taskcluster/docker/infer-build/Dockerfile
rename to taskcluster/docker/static-analysis-build/Dockerfile
--- a/taskcluster/docker/infer-build/Dockerfile
+++ b/taskcluster/docker/static-analysis-build/Dockerfile
@@ -5,26 +5,54 @@ MAINTAINER Robert Bartlensky <rbartlensk
 VOLUME /builds/worker/checkouts
 VOLUME /builds/worker/workspace
 VOLUME /builds/worker/tooltool-cache
 
 ENV XZ_OPT=-T0
 
 RUN apt-get update && \
     apt-get install \
-      autoconf \
+      autoconf2.13 \
+      automake \
       bison \
       bzip2 \
+      cmake \
       flex \
       curl \
-      git \
       opam \
       libsqlite3-dev \
-      autoconf \
-      automake \
-      cmake \
+      file \
+      gawk \
+      gcc-multilib \
+      gnupg \
       libc6-dev \
       openjdk-8-jdk-headless \
       pkg-config \
       patch \
+      p7zip-full \
+      procps \
+      python-pip \
+      python-setuptools \
+      python-virtualenv \
+      rsync \
+      screen \
       tar \
       unzip \
-      zlib1g-dev
+      uuid \
+      valgrind \
+      wget \
+      yasm \
+      zip \
+      zlib1g-dev \
+      x11-utils \
+      xvfb \
+      linux-libc-dev \
+      libdbus-glib-1-dev \
+      libfontconfig1-dev \
+      libfreetype6-dev \
+      libgconf2-dev \
+      libgtk-3-dev \
+      libgtk2.0-dev \
+      libpango1.0-dev \
+      libpulse-dev \
+      libx11-xcb-dev \
+      libxt-dev \
+      lib32z1
new file mode 100755
--- /dev/null
+++ b/taskcluster/scripts/misc/gradle-sa-autotest-dependencies.sh
@@ -0,0 +1,22 @@
+#!/bin/bash -vex
+
+set -x -e
+
+echo "running as" $(id)
+
+: WORKSPACE ${WORKSPACE:=/builds/worker/workspace}
+
+set -v
+
+cd $WORKSPACE/build/src
+
+# Download toolchain artifacts.
+. taskcluster/scripts/misc/tooltool-download.sh
+
+. taskcluster/scripts/misc/android-gradle-dependencies/before.sh
+
+export MOZCONFIG=tools/infer/test/config/mozconfigs/gradle.conf
+./mach configure
+./mach static-analysis autotest-deps
+
+. taskcluster/scripts/misc/gradle-sa-autotest-dependencies/after.sh
new file mode 100755
--- /dev/null
+++ b/taskcluster/scripts/misc/gradle-sa-autotest-dependencies/after.sh
@@ -0,0 +1,29 @@
+#!/bin/bash -vex
+
+set -x -e
+
+echo "running as" $(id)
+
+: WORKSPACE ${WORKSPACE:=/builds/worker/workspace}
+: GRADLE_VERSION ${GRADLE_VERSION:=4.4}
+
+set -v
+
+# Package everything up.
+pushd $WORKSPACE
+mkdir -p gradle-sa-autotest-dependencies /builds/worker/artifacts
+
+cp -R ${NEXUS_WORK}/storage/jcenter gradle-sa-autotest-dependencies
+
+# The Gradle wrapper will have downloaded and verified the hash of exactly one
+# Gradle distribution.  It will be located in $GRADLE_USER_HOME, like
+# ~/.gradle/wrapper/dists/gradle-2.7-all/$PROJECT_HASH/gradle-2.7-all.zip.  We
+# want to remove the version from the internal directory for use via tooltool in
+# a mozconfig.
+cp ${GRADLE_USER_HOME}/wrapper/dists/gradle-${GRADLE_VERSION}-all/*/gradle-${GRADLE_VERSION}-all.zip gradle-${GRADLE_VERSION}-all.zip
+unzip -q gradle-${GRADLE_VERSION}-all.zip
+mv gradle-${GRADLE_VERSION} gradle-sa-autotest-dependencies/gradle-dist
+
+tar cf - gradle-sa-autotest-dependencies | xz > /builds/worker/artifacts/gradle-sa-autotest-dependencies.tar.xz
+
+popd
new file mode 100644
--- /dev/null
+++ b/testing/mozharness/configs/builds/releng_sub_linux_configs/64_sa_autotest.py
@@ -0,0 +1,41 @@
+import os
+
+config = {
+    # note: overridden by MOZHARNESS_ACTIONS in TaskCluster tasks
+    'default_actions': [
+        'clobber',
+        'build',
+    ],
+    'app_ini_path': '%(obj_dir)s/dist/bin/application.ini',
+    # decides whether we want to use moz_sign_cmd in env
+    'vcs_share_base': '/builds/hg-shared',
+    'objdir': 'obj-firefox',
+    #########################################################################
+
+
+    #########################################################################
+    ###### 64 bit specific ######
+    'base_name': 'Linux64 Static-Analysis autotest',
+    'platform': 'linux64',
+    'stage_platform': 'linux64-st-autotest',
+    'env': {
+        'MOZBUILD_STATE_PATH': os.path.join(os.getcwd(), '.mozbuild'),
+        'DISPLAY': ':2',
+        'HG_SHARE_BASE_DIR': '/builds/hg-shared',
+        'MOZ_OBJDIR': '%(abs_obj_dir)s',
+        'TINDERBOX_OUTPUT': '1',
+        'TOOLTOOL_CACHE': '/builds/worker/tooltool-cache',
+        'TOOLTOOL_HOME': '/builds',
+        'MOZ_CRASHREPORTER_NO_REPORT': '1',
+        'LC_ALL': 'C',
+        ## 64 bit specific
+        'PATH': '/usr/local/bin:/bin:\
+/usr/bin:/usr/local/sbin:/usr/sbin:/sbin',
+        ##
+    },
+    # This doesn't actually inherit from anything.
+    'src_mozconfig': 'tools/infer/test/config/mozconfigs/common.conf',
+    'tooltool_manifest_src': 'mobile/android/config/tooltool-manifests/android/releng.manifest',
+    #######################
+    'artifact_flag_build_variant_in_try': None,
+}
--- a/testing/mozharness/mozharness/base/script.py
+++ b/testing/mozharness/mozharness/base/script.py
@@ -1,9 +1,8 @@
-
 #!/usr/bin/env python
 # ***** BEGIN LICENSE BLOCK *****
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 # ***** END LICENSE BLOCK *****
 """Generic script objects.
 
--- a/testing/mozharness/mozharness/mozilla/building/buildbase.py
+++ b/testing/mozharness/mozharness/mozilla/building/buildbase.py
@@ -1221,42 +1221,50 @@ or run without that action (ie: --no-{ac
         self._run_mach_command_in_build_env(['build', '-v'])
 
         self.generate_build_props(console_output=True, halt_on_failure=True)
         self._generate_build_stats()
 
     def static_analysis_autotest(self):
         """Run mach static-analysis autotest, in order to make sure we dont regress"""
         self.preflight_build()
-        self._run_mach_command_in_build_env(['static-analysis', 'autotest', '--intree-tool'])
+        self._run_mach_command_in_build_env(['configure'])
+        self._run_mach_command_in_build_env(['static-analysis', 'autotest',
+                                             '--intree-tool'],
+                                            use_subprocess=True)
 
-    def _run_mach_command_in_build_env(self, args):
+    def _run_mach_command_in_build_env(self, args, use_subprocess=False):
         """Run a mach command in a build context."""
         env = self.query_build_env()
         env.update(self.query_mach_build_env())
-
         dirs = self.query_abs_dirs()
 
         if 'MOZILLABUILD' in os.environ:
             # We found many issues with intermittent build failures when not invoking mach via bash.
             # See bug 1364651 before considering changing.
             mach = [
                 os.path.join(os.environ['MOZILLABUILD'], 'msys', 'bin', 'bash.exe'),
                 os.path.join(dirs['abs_src_dir'], 'mach')
             ]
         else:
             mach = [sys.executable, 'mach']
 
-        return_code = self.run_command(
-            command=mach + ['--log-no-times'] + args,
-            cwd=dirs['abs_src_dir'],
-            env=env,
-            output_timeout=self.config.get('max_build_output_timeout', 60 * 40)
-        )
-
+        # XXX See bug 1483883
+        if use_subprocess:
+            import subprocess
+            return_code = subprocess.call(mach + ['--log-no-times'] + args,
+                                          env=env, cwd=dirs['abs_src_dir'])
+        else:
+            return_code = self.run_command(
+                command=mach + ['--log-no-times'] + args,
+                cwd=dirs['abs_src_dir'],
+                env=env,
+                output_timeout=self.config.get('max_build_output_timeout',
+                                               60 * 40)
+            )
         if return_code:
             self.return_code = self.worst_level(
                 EXIT_STATUS_DICT[TBPL_FAILURE], self.return_code,
                 AUTOMATION_EXIT_CODES[::-1]
             )
             self.fatal("'mach %s' did not run successfully. Please check "
                        "log for errors." % ' '.join(args))
 
--- a/tools/infer/config.yaml
+++ b/tools/infer/config.yaml
@@ -1,23 +1,31 @@
 ---
 target: obj-x86_64-pc-linux-gnu
 # It is used by 'mach static-analysis' and 'mozreview static-analysis bot'
 # in order to have consistency across the used checkers.
 platforms:
   - linux64
 infer_checkers:
+  # no issues were ever trigger by this
   - name: check-nullable
+    publish: !!bool no
+  - name: biabduction
     publish: !!bool yes
+  # very very noisy
+  # it could be useful, but it won't be part of the default enabled checkers
   - name: eradicate
     publish: !!bool no
+  # hard to use, not useful
   - name: quandary
-    publish: !!bool yes
+    publish: !!bool no
   - name: starvation
     publish: !!bool yes
+  # experimental
   - name: litho
-    publish: !!bool yes
+    publish: !!bool no
   - name: racerd
     publish: !!bool yes
+  # I think this is only for c++, can't trigger these errors in Java
   - name: liveness
-    publish: !!bool yes
+    publish: !!bool no
 # Third party files from mozilla-central
 third_party: tools/rewriting/ThirdPartyPaths.txt
new file mode 100644
--- /dev/null
+++ b/tools/infer/test/autotest/build.gradle
@@ -0,0 +1,27 @@
+apply plugin: 'java'
+
+repositories {
+    gradle.mozconfig.substs.GRADLE_SA_MAVEN_REPOSITORIES.each { repository ->
+        maven {
+            url repository
+        }
+    }
+}
+
+dependencies {
+    compile "com.google.code.findbugs:jsr305:3.0.2"
+}
+
+def createSingleTask = { name ->
+    task("compileInferTest${name}", type: JavaCompile) {
+        source = fileTree(dir: '.', include: "src/main/java/${name}.java")
+        classpath = project.configurations.compileClasspath
+        destinationDir = file("build")
+    }
+}
+
+createSingleTask('Biabduction')
+createSingleTask('Checkers')
+createSingleTask('Eradicate')
+createSingleTask('Racerd')
+createSingleTask('Starvation')
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/tools/infer/test/autotest/src/main/java/Biabduction.java
@@ -0,0 +1,22 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import javax.annotation.Nullable;
+import java.util.List;
+
+public class Biabduction {
+    private String get() { return null; }
+
+    public void f1() {
+        get().length(); // error
+    }
+
+    public void f2() {
+        try {
+            get().length(); // error
+        } catch (NullPointerException e) {
+
+        }
+    }
+}
new file mode 100644
--- /dev/null
+++ b/tools/infer/test/autotest/src/main/java/Biabduction.json
@@ -0,0 +1,114 @@
+[
+    {
+        "bug_class": "PROVER",
+        "bug_trace": [
+            {
+                "column_number": -1,
+                "description": "start of procedure f1()",
+                "filename": "autotest/src/main/java/Biabduction.java",
+                "level": 0,
+                "line_number": 11
+            },
+            {
+                "column_number": -1,
+                "description": "",
+                "filename": "autotest/src/main/java/Biabduction.java",
+                "level": 0,
+                "line_number": 12
+            },
+            {
+                "column_number": -1,
+                "description": "start of procedure get()",
+                "filename": "autotest/src/main/java/Biabduction.java",
+                "level": 1,
+                "line_number": 9
+            },
+            {
+                "column_number": -1,
+                "description": "return from a call to String Biabduction.get()",
+                "filename": "autotest/src/main/java/Biabduction.java",
+                "level": 1,
+                "line_number": 9
+            },
+            {
+                "column_number": -1,
+                "description": "",
+                "filename": "autotest/src/main/java/Biabduction.java",
+                "level": 0,
+                "line_number": 12
+            }
+        ],
+        "bug_type": "NULL_DEREFERENCE",
+        "bug_type_hum": "Null Dereference",
+        "censored_reason": "",
+        "column": -1,
+        "file": "autotest/src/main/java/Biabduction.java",
+        "hash": "918d7eaedf45f651f04c55554c72478c",
+        "key": "Biabduction.java|f1|NULL_DEREFERENCE",
+        "kind": "ERROR",
+        "line": 12,
+        "node_key": "9afcdcc9d4253c36267a0d34b98c337d",
+        "procedure": "void Biabduction.f1()",
+        "procedure_id": "Biabduction.f1():void.4b49520e7621606a0d5661886ff0b098",
+        "procedure_start_line": 11,
+        "qualifier": "object returned by `get(this)` could be null and is dereferenced at line 12.",
+        "severity": "HIGH",
+        "visibility": "user"
+    },
+    {
+        "bug_class": "PROVER",
+        "bug_trace": [
+            {
+                "column_number": -1,
+                "description": "start of procedure f2()",
+                "filename": "autotest/src/main/java/Biabduction.java",
+                "level": 0,
+                "line_number": 15
+            },
+            {
+                "column_number": -1,
+                "description": "",
+                "filename": "autotest/src/main/java/Biabduction.java",
+                "level": 0,
+                "line_number": 17
+            },
+            {
+                "column_number": -1,
+                "description": "start of procedure get()",
+                "filename": "autotest/src/main/java/Biabduction.java",
+                "level": 1,
+                "line_number": 9
+            },
+            {
+                "column_number": -1,
+                "description": "return from a call to String Biabduction.get()",
+                "filename": "autotest/src/main/java/Biabduction.java",
+                "level": 1,
+                "line_number": 9
+            },
+            {
+                "column_number": -1,
+                "description": "",
+                "filename": "autotest/src/main/java/Biabduction.java",
+                "level": 0,
+                "line_number": 17
+            }
+        ],
+        "bug_type": "NULL_DEREFERENCE",
+        "bug_type_hum": "Null Dereference",
+        "censored_reason": "",
+        "column": -1,
+        "file": "autotest/src/main/java/Biabduction.java",
+        "hash": "bc952ce8bad58dac5cb6672dc3150524",
+        "key": "Biabduction.java|f2|NULL_DEREFERENCE",
+        "kind": "ERROR",
+        "line": 17,
+        "node_key": "9afcdcc9d4253c36267a0d34b98c337d",
+        "procedure": "void Biabduction.f2()",
+        "procedure_id": "Biabduction.f2():void.41c05a632eb912a458482c1e2e4dcbb4",
+        "procedure_start_line": 15,
+        "qualifier": "object returned by `get(this)` could be null and is dereferenced at line 17.",
+        "severity": "HIGH",
+        "visibility": "user"
+    }
+]
new file mode 100644
--- /dev/null
+++ b/tools/infer/test/autotest/src/main/java/Checkers.java
@@ -0,0 +1,34 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+
+public class Checkers {
+    public static void leak() {
+        try {
+            BufferedReader br = new BufferedReader(
+                new FileReader(new File("some.txt"))
+            );
+        } catch (Exception e) {
+
+        }
+    }
+
+    public static void error1() {
+        String str = null;
+        try {
+            int x = str.length(); // Error: even if exception is caught
+        } catch (NullPointerException e) {
+
+        }
+    }
+
+    public static void error2() {
+        String str = null;
+        int x = str.length(); // Error: not checking for null
+    }
+
+}
new file mode 100644
--- /dev/null
+++ b/tools/infer/test/autotest/src/main/java/Checkers.json
@@ -0,0 +1,121 @@
+[
+    {
+        "bug_class": "PROVER",
+        "bug_trace": [
+            {
+                "column_number": -1,
+                "description": "start of procedure leak()",
+                "filename": "autotest/src/main/java/Checkers.java",
+                "level": 0,
+                "line_number": 10
+            },
+            {
+                "column_number": -1,
+                "description": "",
+                "filename": "autotest/src/main/java/Checkers.java",
+                "level": 0,
+                "line_number": 12
+            }
+        ],
+        "bug_type": "RESOURCE_LEAK",
+        "bug_type_hum": "Resource Leak",
+        "censored_reason": "",
+        "column": -1,
+        "file": "autotest/src/main/java/Checkers.java",
+        "hash": "56806153823413731f2e2166ed8d30a0",
+        "key": "Checkers.java|leak|RESOURCE_LEAK",
+        "kind": "ERROR",
+        "line": 12,
+        "node_key": "3a2af627d5d1f10e1994f6259cf18e4c",
+        "procedure": "void Checkers.leak()",
+        "procedure_id": "Checkers.leak():void.e21648e10d3037f4559cdb7c08642c84",
+        "procedure_start_line": 10,
+        "qualifier": "resource of type `java.io.FileReader` acquired by call to `new()` at line 12 is not released after line 12.",
+        "severity": "HIGH",
+        "visibility": "user"
+    },
+    {
+        "bug_class": "PROVER",
+        "bug_trace": [
+            {
+                "column_number": -1,
+                "description": "start of procedure error1()",
+                "filename": "autotest/src/main/java/Checkers.java",
+                "level": 0,
+                "line_number": 20
+            },
+            {
+                "column_number": -1,
+                "description": "",
+                "filename": "autotest/src/main/java/Checkers.java",
+                "level": 0,
+                "line_number": 21
+            },
+            {
+                "column_number": -1,
+                "description": "",
+                "filename": "autotest/src/main/java/Checkers.java",
+                "level": 0,
+                "line_number": 23
+            }
+        ],
+        "bug_type": "NULL_DEREFERENCE",
+        "bug_type_hum": "Null Dereference",
+        "censored_reason": "",
+        "column": -1,
+        "file": "autotest/src/main/java/Checkers.java",
+        "hash": "6de26e7c66c71b1114ad233679d55640",
+        "key": "Checkers.java|error1|NULL_DEREFERENCE",
+        "kind": "ERROR",
+        "line": 23,
+        "node_key": "c281f77c6dae544ee5fb7d5e2bb35118",
+        "procedure": "void Checkers.error1()",
+        "procedure_id": "Checkers.error1():void.59417424d80960700a32012973e98db5",
+        "procedure_start_line": 20,
+        "qualifier": "object `str` last assigned on line 21 could be null and is dereferenced at line 23.",
+        "severity": "HIGH",
+        "visibility": "user"
+    },
+    {
+        "bug_class": "PROVER",
+        "bug_trace": [
+            {
+                "column_number": -1,
+                "description": "start of procedure error2()",
+                "filename": "autotest/src/main/java/Checkers.java",
+                "level": 0,
+                "line_number": 29
+            },
+            {
+                "column_number": -1,
+                "description": "",
+                "filename": "autotest/src/main/java/Checkers.java",
+                "level": 0,
+                "line_number": 30
+            },
+            {
+                "column_number": -1,
+                "description": "",
+                "filename": "autotest/src/main/java/Checkers.java",
+                "level": 0,
+                "line_number": 31
+            }
+        ],
+        "bug_type": "NULL_DEREFERENCE",
+        "bug_type_hum": "Null Dereference",
+        "censored_reason": "",
+        "column": -1,
+        "file": "autotest/src/main/java/Checkers.java",
+        "hash": "39e021b634ab428af7be2034688491a7",
+        "key": "Checkers.java|error2|NULL_DEREFERENCE",
+        "kind": "ERROR",
+        "line": 31,
+        "node_key": "c281f77c6dae544ee5fb7d5e2bb35118",
+        "procedure": "void Checkers.error2()",
+        "procedure_id": "Checkers.error2():void.e9146d80ba20c908c11d08947cd89d06",
+        "procedure_start_line": 29,
+        "qualifier": "object `str` last assigned on line 30 could be null and is dereferenced at line 31.",
+        "severity": "HIGH",
+        "visibility": "user"
+    }
+]
new file mode 100644
--- /dev/null
+++ b/tools/infer/test/autotest/src/main/java/Eradicate.java
@@ -0,0 +1,57 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import javax.annotation.Nullable;
+
+// Examples taken from the infer website.
+public class Eradicate {
+
+    public String f; // Because it is not annoted with nullable -> can never be null!
+
+    public void field(@Nullable Eradicate x) {
+        x.f = "3"; // Error: Eradicate null field access
+    }
+
+    public void method(@Nullable Object x) {
+        String s = x.toString(); // Error: Eradicate null method call
+    }
+
+    public void filedNotNull(@Nullable String s) {
+        f = s; // Error: Eradicate field not nullable
+    }
+
+    public Eradicate() {} // Error: Eradicate field not initialized
+
+    public void str(Eradicate x) {
+        String s = x.toString();
+    }
+
+    public void callStr(@Nullable Eradicate x) {
+        str(x); // Error:  Eradicate parameter not nullable
+    }
+
+    public String shouldNotReturnNullBecauseNotAnnotated() {
+        return null; // Error: Eradicate return not nullable
+    }
+
+    public void redundant() {
+        String s = new String("abc");
+        if (s != null) { // Error: Eradicate condition redundant
+            int n = s.length();
+        }
+    }
+
+    @Nullable
+    public static String someMethod() {
+        return ""; // Error: Eradicate return overannotated
+    }
+}
+
+class B extends Eradicate {
+    @Nullable public String shouldNotReturnNullBecauseNotAnnotated() {
+        return null; // Error: Eradicate inconsistent subclass return annotation
+    }
+
+    public void field(Eradicate x) {} // Error: Inconsistent subclass parameter annotation
+}
new file mode 100644
--- /dev/null
+++ b/tools/infer/test/autotest/src/main/java/Racerd.java
@@ -0,0 +1,40 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import javax.annotation.concurrent.ThreadSafe;
+
+// Examples taken from the infer website.
+@ThreadSafe
+public class Racerd {
+    private int mTemperature;
+
+    public void makeDinner() {
+        boilWater();
+    }
+
+    private void boilWater() {
+        mTemperature = 100; //Error: unprotected write.
+    }
+}
+
+@ThreadSafe
+class Account {
+
+    int mBalance = 0;
+
+    public void deposit(int amount) {
+        if (amount > 0) {
+            mBalance += amount; // Error: unsynchronized write
+        }
+    }
+
+    public int withdraw(int amount){
+        if (amount >= 0 && mBalance - amount >= 0) {
+            mBalance -= amount; // Error: unsynchronized write
+            return mBalance; // Error: unsynchronized read
+        } else {
+            return 0;
+        }
+    }
+}
new file mode 100644
--- /dev/null
+++ b/tools/infer/test/autotest/src/main/java/Racerd.json
@@ -0,0 +1,146 @@
+[
+    {
+        "access": "hJWmvgAAAJMAAAApAAAAfgAAAHSwkNAnZGVwb3NpdKCgQCNpbnRAk6AnQWNjb3VudECQoEAkdm9pZECgoJKgIECwXAD/kgkiYXV0b3Rlc3Qvc3JjL21haW4vamF2YS9SYWNlcmQuamF2YZGgoJGwAjafTBegJHRoaXNAkAQcoKOglJOgBBpAsEBAQEAEAaCRkTBBY2NvdW50Lm1CYWxhbmNlQKAEF0A=",
+        "bug_class": "PROVER",
+        "bug_trace": [
+            {
+                "column_number": -1,
+                "description": "access to `this.Account.mBalance`",
+                "filename": "autotest/src/main/java/Racerd.java",
+                "level": 0,
+                "line_number": 28
+            }
+        ],
+        "bug_type": "THREAD_SAFETY_VIOLATION",
+        "bug_type_hum": "Thread Safety Violation",
+        "censored_reason": "",
+        "column": -1,
+        "file": "autotest/src/main/java/Racerd.java",
+        "hash": "6b62cb17008a3135d218108fa3123402",
+        "key": "Racerd.java|deposit|THREAD_SAFETY_VIOLATION",
+        "kind": "ERROR",
+        "line": 28,
+        "node_key": "9c5d6d9028928346cc4fb44cced5dea1",
+        "procedure": "void Account.deposit(int)",
+        "procedure_id": "Account.deposit(int):void.a9cc1805c1e3652887a5ee12b55803af",
+        "procedure_start_line": 0,
+        "qualifier": "Unprotected write. Non-private method `void Account.deposit(int)` writes to field `this.Account.mBalance` outside of synchronization.\n Reporting because the current class is annotated `@ThreadSafe`, so we assume that this method can run in parallel with other non-private methods in the class (including itself).",
+        "severity": "HIGH",
+        "visibility": "user"
+    },
+    {
+        "access": "hJWmvgAAAKYAAAApAAAAhQAAAHqwkNAqbWFrZURpbm5lckCToCZSYWNlcmRAkKBAJHZvaWRAoKCQ0Clib2lsV2F0ZXJAk6AEC0AECkCwTQD/kgkiYXV0b3Rlc3Qvc3JjL21haW4vamF2YS9SYWNlcmQuamF2YZGgoJGwAjafTBegJHRoaXNAkAQboKOglJOgBBxAsEBAQEAEAaCRkTNSYWNlcmQubVRlbXBlcmF0dXJlQKCwUQD/BBdA",
+        "bug_class": "PROVER",
+        "bug_trace": [
+            {
+                "column_number": -1,
+                "description": "call to void Racerd.boilWater()",
+                "filename": "autotest/src/main/java/Racerd.java",
+                "level": 0,
+                "line_number": 13
+            },
+            {
+                "column_number": -1,
+                "description": "access to `this.Racerd.mTemperature`",
+                "filename": "autotest/src/main/java/Racerd.java",
+                "level": 1,
+                "line_number": 17
+            }
+        ],
+        "bug_type": "THREAD_SAFETY_VIOLATION",
+        "bug_type_hum": "Thread Safety Violation",
+        "censored_reason": "",
+        "column": -1,
+        "file": "autotest/src/main/java/Racerd.java",
+        "hash": "2882383086ab102a88144ae3c2cc4701",
+        "key": "Racerd.java|makeDinner|THREAD_SAFETY_VIOLATION",
+        "kind": "ERROR",
+        "line": 13,
+        "node_key": "9c5d6d9028928346cc4fb44cced5dea1",
+        "procedure": "void Racerd.makeDinner()",
+        "procedure_id": "Racerd.makeDinner():void.2796f75396b30d2d49b24ddfab722306",
+        "procedure_start_line": 0,
+        "qualifier": "Unprotected write. Non-private method `void Racerd.makeDinner()` indirectly writes to field `this.Racerd.mTemperature` outside of synchronization.\n Reporting because the current class is annotated `@ThreadSafe`, so we assume that this method can run in parallel with other non-private methods in the class (including itself).",
+        "severity": "HIGH",
+        "visibility": "user"
+    },
+    {
+        "access": "hJWmvgAAAJgAAAAqAAAAgwAAAHqwkNAod2l0aGRyYXegoEAjaW50QJOgJ0FjY291bnRAkKBABAZAoKCSoCBAsGMA/5IJImF1dG90ZXN0L3NyYy9tYWluL2phdmEvUmFjZXJkLmphdmGQoKCRsAI2n0wXoCR0aGlzQJAEG6CjoJSToAQZQLBAQEBABAGgkZEwQWNjb3VudC5tQmFsYW5jZUCgBBegsGIA/wQYQA==",
+        "bug_class": "PROVER",
+        "bug_trace": [
+            {
+                "column_number": -1,
+                "description": "<Read trace>",
+                "filename": "autotest/src/main/java/Racerd.java",
+                "level": 0,
+                "line_number": 35
+            },
+            {
+                "column_number": -1,
+                "description": "access to `this.Account.mBalance`",
+                "filename": "autotest/src/main/java/Racerd.java",
+                "level": 0,
+                "line_number": 35
+            },
+            {
+                "column_number": -1,
+                "description": "<Write trace>",
+                "filename": "autotest/src/main/java/Racerd.java",
+                "level": 0,
+                "line_number": 34
+            },
+            {
+                "column_number": -1,
+                "description": "access to `this.Account.mBalance`",
+                "filename": "autotest/src/main/java/Racerd.java",
+                "level": 0,
+                "line_number": 34
+            }
+        ],
+        "bug_type": "THREAD_SAFETY_VIOLATION",
+        "bug_type_hum": "Thread Safety Violation",
+        "censored_reason": "",
+        "column": -1,
+        "file": "autotest/src/main/java/Racerd.java",
+        "hash": "5665f12d2392f93f11f556cd1b1e238a",
+        "key": "Racerd.java|withdraw|THREAD_SAFETY_VIOLATION",
+        "kind": "ERROR",
+        "line": 35,
+        "node_key": "9c5d6d9028928346cc4fb44cced5dea1",
+        "procedure": "int Account.withdraw(int)",
+        "procedure_id": "Account.withdraw(int):int.038de5054c5c25e60d169e42e0177a16",
+        "procedure_start_line": 0,
+        "qualifier": "Read/Write race. Non-private method `int Account.withdraw(int)` reads without synchronization from `this.Account.mBalance`. Potentially races with write in method `Account.withdraw(...)`.\n Reporting because the current class is annotated `@ThreadSafe`, so we assume that this method can run in parallel with other non-private methods in the class (including itself).",
+        "severity": "HIGH",
+        "visibility": "user"
+    },
+    {
+        "access": "hJWmvgAAAJEAAAAoAAAAfAAAAHOwkNAod2l0aGRyYXegoEAjaW50QJOgJ0FjY291bnRAkKBABAZAoKCSoCBAsGIA/5IJImF1dG90ZXN0L3NyYy9tYWluL2phdmEvUmFjZXJkLmphdmGRoKCRsAI2n0wXoCR0aGlzQJAEG6CjoJSToAQZQLBAQEBABAGgkZEwQWNjb3VudC5tQmFsYW5jZUCgBBdA",
+        "bug_class": "PROVER",
+        "bug_trace": [
+            {
+                "column_number": -1,
+                "description": "access to `this.Account.mBalance`",
+                "filename": "autotest/src/main/java/Racerd.java",
+                "level": 0,
+                "line_number": 34
+            }
+        ],
+        "bug_type": "THREAD_SAFETY_VIOLATION",
+        "bug_type_hum": "Thread Safety Violation",
+        "censored_reason": "",
+        "column": -1,
+        "file": "autotest/src/main/java/Racerd.java",
+        "hash": "a7c30fd1b251d9e16750fc7e5913b885",
+        "key": "Racerd.java|withdraw|THREAD_SAFETY_VIOLATION",
+        "kind": "ERROR",
+        "line": 34,
+        "node_key": "9c5d6d9028928346cc4fb44cced5dea1",
+        "procedure": "int Account.withdraw(int)",
+        "procedure_id": "Account.withdraw(int):int.038de5054c5c25e60d169e42e0177a16",
+        "procedure_start_line": 0,
+        "qualifier": "Unprotected write. Non-private method `int Account.withdraw(int)` writes to field `this.Account.mBalance` outside of synchronization.\n Reporting because the current class is annotated `@ThreadSafe`, so we assume that this method can run in parallel with other non-private methods in the class (including itself).",
+        "severity": "HIGH",
+        "visibility": "user"
+    }
+]
new file mode 100644
--- /dev/null
+++ b/tools/infer/test/autotest/src/main/java/Starvation.java
@@ -0,0 +1,25 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// Examples taken from the infer website.
+public class Starvation {
+
+    String lockA, lockB;
+
+    public void lockAThenB() {
+        synchronized(lockA) {
+            synchronized(lockB) {
+                // do something with both resources
+            }
+        }
+    }
+
+    public void lockBThenA() {
+        synchronized(lockB) {
+            synchronized(lockA) {
+                // do something with both resources
+            }
+        }
+    }
+}
new file mode 100644
--- /dev/null
+++ b/tools/infer/test/autotest/src/main/java/Starvation.json
@@ -0,0 +1,65 @@
+[
+    {
+        "bug_class": "PROVER",
+        "bug_trace": [
+            {
+                "column_number": -1,
+                "description": "[Trace 1] `void Starvation.lockAThenB()`",
+                "filename": "autotest/src/main/java/Starvation.java",
+                "level": 0,
+                "line_number": 11
+            },
+            {
+                "column_number": -1,
+                "description": "locks `this.Starvation.lockA` in class `Starvation*`",
+                "filename": "autotest/src/main/java/Starvation.java",
+                "level": 0,
+                "line_number": 11
+            },
+            {
+                "column_number": -1,
+                "description": "locks `this.Starvation.lockB` in class `Starvation*`",
+                "filename": "autotest/src/main/java/Starvation.java",
+                "level": 1,
+                "line_number": 12
+            },
+            {
+                "column_number": -1,
+                "description": "[Trace 2] `void Starvation.lockBThenA()`",
+                "filename": "autotest/src/main/java/Starvation.java",
+                "level": 0,
+                "line_number": 19
+            },
+            {
+                "column_number": -1,
+                "description": "locks `this.Starvation.lockB` in class `Starvation*`",
+                "filename": "autotest/src/main/java/Starvation.java",
+                "level": 0,
+                "line_number": 19
+            },
+            {
+                "column_number": -1,
+                "description": "locks `this.Starvation.lockA` in class `Starvation*`",
+                "filename": "autotest/src/main/java/Starvation.java",
+                "level": 1,
+                "line_number": 20
+            }
+        ],
+        "bug_type": "DEADLOCK",
+        "bug_type_hum": "Deadlock",
+        "censored_reason": "",
+        "column": -1,
+        "file": "autotest/src/main/java/Starvation.java",
+        "hash": "043d28a94431b4c573b949b8570fb318",
+        "key": "Starvation.java|lockAThenB|DEADLOCK",
+        "kind": "ERROR",
+        "line": 11,
+        "node_key": "9c5d6d9028928346cc4fb44cced5dea1",
+        "procedure": "void Starvation.lockAThenB()",
+        "procedure_id": "Starvation.lockAThenB():void.b7eb3955306c498af42d6336f52a796f",
+        "procedure_start_line": 0,
+        "qualifier": "Potential deadlock.\nTrace 1 (starts at `void Starvation.lockAThenB()`) first locks `this.Starvation.lockA` in class `Starvation*` (line 11 in `void Starvation.lockAThenB()`) and then locks `this.Starvation.lockB` in class `Starvation*` (line 12 in `void Starvation.lockAThenB()`).\nTrace 2 (starts at `void Starvation.lockBThenA()`), first locks `this.Starvation.lockB` in class `Starvation*` (line 19 in `void Starvation.lockBThenA()`) and then locks `this.Starvation.lockA` in class `Starvation*` (line 20 in `void Starvation.lockBThenA()`).",
+        "severity": "HIGH",
+        "visibility": "user"
+    }
+]
new file mode 100644
--- /dev/null
+++ b/tools/infer/test/config/mozconfigs/common.conf
@@ -0,0 +1,10 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+# let's install gradle first
+ac_add_options --with-gradle-sa="$topsrcdir/gradle-sa-autotest-dependencies/gradle-dist/bin/gradle"
+export GRADLE_SA_MAVEN_REPOSITORIES="file://$topsrcdir/gradle-sa-autotest-dependencies/jcenter"
+
+. "$topsrcdir/build/mozconfig.no-compile"
+ac_add_options --disable-tests
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/tools/infer/test/config/mozconfigs/gradle.conf
@@ -0,0 +1,13 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+# let's install gradle first
+ac_add_options --with-gradle-sa
+export GRADLE_SA_MAVEN_REPOSITORIES="http://localhost:8081/nexus/content/repositories/jcenter/"
+
+
+ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
+
+. "$topsrcdir/build/mozconfig.no-compile"
+ac_add_options --disable-tests
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/tools/infer/test/gradle.properties
@@ -0,0 +1,3 @@
+org.gradle.parallel=true
+org.gradle.daemon=true
+org.gradle.jvmargs=-Xmx2560M
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..01b8bf6b1f99cad9213fc495b33ad5bbab8efd20
GIT binary patch
literal 54329
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
bJ^ynAMotn0^tb<Ec>B|RYueZI+ur{Jl(6YG
new file mode 100644
--- /dev/null
+++ b/tools/infer/test/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
new file mode 100755
--- /dev/null
+++ b/tools/infer/test/gradlew
@@ -0,0 +1,172 @@
+#!/usr/bin/env sh
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+    echo "$*"
+}
+
+die () {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+  NONSTOP* )
+    nonstop=true
+    ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+    JAVACMD=`cygpath --unix "$JAVACMD"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=$((i+1))
+    done
+    case $i in
+        (0) set -- ;;
+        (1) set -- "$args0" ;;
+        (2) set -- "$args0" "$args1" ;;
+        (3) set -- "$args0" "$args1" "$args2" ;;
+        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Escape application args
+save () {
+    for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+    echo " "
+}
+APP_ARGS=$(save "$@")
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+  cd "$(dirname "$0")"
+fi
+
+exec "$JAVACMD" "$@"
new file mode 100644
--- /dev/null
+++ b/tools/infer/test/gradlew.bat
@@ -0,0 +1,84 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem  Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
new file mode 100644
--- /dev/null
+++ b/tools/infer/test/moz.configure
@@ -0,0 +1,68 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+option('--with-gradle-sa', nargs='?',
+       default=True,
+       help='Enable building mobile/android with Gradle '
+            '(argument: location of binary or wrapper (gradle/gradlew))')
+
+@depends('--with-gradle-sa')
+def with_gradle_sa(value):
+    if not value:
+        die('Building --without-gradle-sa is no longer supported: '
+            'see https://bugzilla.mozilla.org/show_bug.cgi?id=1414415.')
+    if value:
+        return True
+
+@depends('--with-gradle-sa', check_build_environment)
+@imports(_from='os.path', _import='isfile')
+def gradle_sa_autotest(value, build_env):
+    gradle = value[0] if len(value) else \
+        os.path.join(build_env.topsrcdir, 'tools', 'infer', 'test', 'gradlew')
+    # TODO: verify that $GRADLE is executable.
+    if not isfile(gradle):
+        die('GRADLE must be executable: %s', gradle)
+    return gradle
+
+set_config('GRADLE_SA_AUTOTEST', gradle_sa_autotest)
+
+@dependable
+def gradle_infer_autotest_tasks():
+    '''Gradle tasks executed by |mach static-analysis autotest|'''
+    return ['autotest:compileInferTestBiabduction',
+            'autotest:compileInferTestCheckers',
+            'autotest:compileInferTestEradicate',
+            'autotest:compileInferTestRacerd',
+            'autotest:compileInferTestStarvation']
+
+set_config('GRADLE_INFER_AUTOTEST_TASKS', gradle_infer_autotest_tasks)
+
+@depends(build_project)
+def java_include(build_project):
+    if build_project == 'mobile/android':
+        return None
+    return '../../../build/moz.configure/java.configure'
+
+include(java_include)
+
+# Automation will set this to (file:///path/to/local, ...) via the mozconfig.
+# Local developer default is (jcenter, maven.google.com).
+option(env='GRADLE_SA_MAVEN_REPOSITORIES',
+       nargs='+',
+       default=('https://jcenter.bintray.com/'),
+       help='Comma-separated URLs of Maven repositories containing Gradle '
+       'dependencies for static-analaysis autotest.')
+
+@depends('GRADLE_SA_MAVEN_REPOSITORIES')
+@imports(_from='os.path', _import='isdir')
+def gradle_sa_maven_repositories(values):
+    if not values:
+        die('GRADLE_SA_MAVEN_REPOSITORIES must not be empty')
+    if not all(values):
+        die('GRADLE_SA_MAVEN_REPOSITORIES entries must not be empty')
+    return values
+
+set_config('GRADLE_SA_MAVEN_REPOSITORIES', gradle_sa_maven_repositories)
new file mode 100644
--- /dev/null
+++ b/tools/infer/test/settings.gradle
@@ -0,0 +1,36 @@
+/*
+ * This settings file was auto generated by the Gradle buildInit task
+ * by 'robert' at '08/08/18 12:25' with Gradle 3.2.1
+ *
+ * The settings file is used to specify which projects to include in your build.
+ * In a single project build this file can be empty or even removed.
+ *
+ * Detailed information about configuring a multi-project build in Gradle can be found
+ * in the user guide at https://docs.gradle.org/3.2.1/userguide/multi_project_builds.html
+ */
+
+// You might think topsrcdir is '.', but that's not true when the Gradle build
+// is launched from within IntelliJ.
+def topsrcdir = rootProject.projectDir.absolutePath
+
+def commandLine = ["${topsrcdir}/../../../mach", "environment", "--format", "json", "--verbose"]
+def proc = commandLine.execute(null, new File(topsrcdir))
+def standardOutput = new ByteArrayOutputStream()
+proc.consumeProcessOutput(standardOutput, standardOutput)
+proc.waitFor()
+
+// Only show the output if something went wrong.
+if (proc.exitValue() != 0) {
+    throw new GradleException("Process '${commandLine}' finished with non-zero exit value ${proc.exitValue()}:\n\n${standardOutput.toString()}")
+}
+
+import groovy.json.JsonSlurper
+
+def slurper = new JsonSlurper()
+def json = slurper.parseText(standardOutput.toString())
+
+rootProject.name = 'infer'
+
+include 'autotest'
+
+gradle.ext.mozconfig = json