Merge "Support multiple arch for coverage packaging."
diff --git a/core/Makefile b/core/Makefile
index 7a1041a..42d42bb 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -873,6 +873,10 @@
 $(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VBOOT),$(hide) echo "vboot_subkey=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VBOOT_SIGNING_SUBKEY)" >> $(1))
 $(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VBOOT),$(hide) echo "futility=$(FUTILITY)" >> $(1))
 $(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VBOOT),$(hide) echo "vboot_signer_cmd=$(VBOOT_SIGNER)" >> $(1))
+$(if $(BOARD_AVB_ENABLE),$(hide) echo "avb_signing_args=$(INTERNAL_AVB_SIGNING_ARGS)" >> $(1))
+$(if $(BOARD_AVB_ENABLE),$(hide) echo "avb_avbtool=$(AVBTOOL)" >> $(1))
+$(if $(BOARD_AVB_ENABLE),$(hide) echo "system_avb_enable=$(BOARD_AVB_ENABLE)" >> $(1))
+$(if $(BOARD_AVB_ENABLE),$(hide) echo "system_avb_add_hashtree_footer_args=$(BOARD_AVB_SYSTEM_ADD_HASHTREE_FOOTER_ARGS)" >> $(1))
 $(if $(filter true,$(BOARD_USES_RECOVERY_AS_BOOT)),\
     $(hide) echo "recovery_as_boot=true" >> $(1))
 $(if $(filter true,$(BOARD_BUILD_SYSTEM_ROOT_IMAGE)),\
@@ -1180,13 +1184,6 @@
            fi; \
            mkdir -p $(DIST_DIR); cp $(INSTALLED_FILES_FILE) $(DIST_DIR)/installed-files-rescued.txt; \
            exit 1 )
-  $(if $(BOARD_AVB_ENABLE), \
-    $(hide) $(AVBTOOL) add_hashtree_footer \
-      --image $(1) \
-      --partition_size $(BOARD_SYSTEMIMAGE_PARTITION_SIZE) \
-      --partition_name system \
-      $(INTERNAL_AVB_SIGNING_ARGS) \
-      $(BOARD_AVB_SYSTEM_ADD_HASHTREE_FOOTER_ARGS))
 endef
 
 $(BUILT_SYSTEMIMAGE): $(FULL_SYSTEMIMAGE_DEPS) $(INSTALLED_FILES_FILE) $(BUILD_IMAGE_SRCS)
diff --git a/core/base_rules.mk b/core/base_rules.mk
index 56df2a9..13d20e0 100644
--- a/core/base_rules.mk
+++ b/core/base_rules.mk
@@ -269,9 +269,6 @@
 # dependent binaries of a .toc file will be rebuilt only when the content of
 # the .toc file is changed.
 ###########################################################
-ifndef LOCAL_IS_HOST_MODULE
-# Disable .toc optimization for host modules: we may run the host binaries during the build process
-# and the libraries' implementation matters.
 ifeq ($(LOCAL_MODULE_CLASS),SHARED_LIBRARIES)
 LOCAL_INTERMEDIATE_TARGETS += $(LOCAL_BUILT_MODULE).toc
 $(LOCAL_BUILT_MODULE).toc: $(LOCAL_BUILT_MODULE)
@@ -283,7 +280,6 @@
 # Build .toc file when using mm, mma, or make $(my_register_name)
 $(my_all_targets): $(LOCAL_BUILT_MODULE).toc
 endif
-endif
 
 ###########################################################
 ## logtags: Add .logtags files to global list
diff --git a/core/binary.mk b/core/binary.mk
index 6413153..4dcb152 100644
--- a/core/binary.mk
+++ b/core/binary.mk
@@ -1507,13 +1507,7 @@
     $(addprefix $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)OUT_INTERMEDIATE_LIBRARIES)/, \
       $(addsuffix $(so_suffix), \
         $(installed_shared_library_module_names)))
-ifdef LOCAL_IS_HOST_MODULE
-# Disable .toc optimization for host modules: we may run the host binaries during the build process
-# and the libraries' implementation matters.
-built_shared_library_deps := $(built_shared_libraries)
-else
 built_shared_library_deps := $(addsuffix .toc, $(built_shared_libraries))
-endif
 my_system_shared_libraries_fullpath :=
 endif
 
diff --git a/core/clang/tidy.mk b/core/clang/tidy.mk
index c156f31..a081056 100644
--- a/core/clang/tidy.mk
+++ b/core/clang/tidy.mk
@@ -18,7 +18,7 @@
 # Global tidy checks include only google*, performance*,
 # and misc-macro-parentheses, but not google-readability*
 # or google-runtime-references.
-DEFAULT_GLOBAL_TIDY_CHECKS := \
+DEFAULT_GLOBAL_TIDY_CHECKS ?= \
   $(subst $(space),, \
     -*,google* \
     ,misc-macro-parentheses \
@@ -29,7 +29,7 @@
 
 # There are too many clang-tidy warnings in external and vendor projects.
 # Enable only some google checks for these projects.
-DEFAULT_EXTERNAL_VENDOR_TIDY_CHECKS := \
+DEFAULT_EXTERNAL_VENDOR_TIDY_CHECKS ?= \
   $(subst $(space),, \
     -*,google* \
     ,-google-build-using-namespace \
diff --git a/core/config.mk b/core/config.mk
index da4784f..bab31b7 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -148,7 +148,7 @@
 
 # Pruned directory options used when using findleaves.py
 # See envsetup.mk for a description of SCAN_EXCLUDE_DIRS
-FIND_LEAVES_EXCLUDES := $(addprefix --prune=, $(OUT_DIR) $(SCAN_EXCLUDE_DIRS) .repo .git)
+FIND_LEAVES_EXCLUDES := $(addprefix --prune=, $(SCAN_EXCLUDE_DIRS) .repo .git)
 
 # The build system exposes several variables for where to find the kernel
 # headers:
@@ -225,7 +225,7 @@
 # Commands to generate .toc file from Darwin dynamic library.
 define _gen_toc_command_for_macho
 $(hide) otool -l $(1) | grep LC_ID_DYLIB -A 5 > $(2)
-$(hide) nm -gP $(1) | cut -f1-2 -d" " | grep -v U$$ >> $(2)
+$(hide) nm -gP $(1) | cut -f1-2 -d" " | (grep -v U$$ >> $(2) || true)
 endef
 
 combo_target := HOST_
diff --git a/core/dex_preopt_libart.mk b/core/dex_preopt_libart.mk
index 5a2f07f..ab54b1d 100644
--- a/core/dex_preopt_libart.mk
+++ b/core/dex_preopt_libart.mk
@@ -25,10 +25,6 @@
 COMPILED_CLASSES := $(call word-colon,1,$(firstword \
     $(filter %system/etc/compiled-classes,$(PRODUCT_COPY_FILES))))
 
-# start of image reserved address space
-LIBART_IMG_HOST_BASE_ADDRESS   := 0x60000000
-LIBART_IMG_TARGET_BASE_ADDRESS := 0x70000000
-
 define get-product-default-property
 $(strip $(patsubst $(1)=%,%,$(filter $(1)=%,$(PRODUCT_DEFAULT_PROPERTY_OVERRIDES))))
 endef
@@ -45,7 +41,6 @@
 # building the image. We therefore limit the Xmx value. This isn't done
 # via a property as we want the larger Xmx value if we're running on a
 # MIPS device.
-LIBART_IMG_TARGET_BASE_ADDRESS := 0x30000000
 DEX2OAT_XMX := 128m
 endif
 
diff --git a/core/main.mk b/core/main.mk
index fee2995..de77927 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -660,6 +660,14 @@
 $(1): | $(2)
 endef
 
+# Use a normal dependency instead of an order-only dependency when installing
+# host dynamic binaries so that the timestamp of the final binary always
+# changes, even if the toc optimization has skipped relinking the binary
+# and its dependant shared libraries.
+define add-required-host-so-deps
+$(1): $(2)
+endef
+
 $(foreach m,$(ALL_MODULES), \
   $(eval r := $(ALL_MODULES.$(m).REQUIRED)) \
   $(if $(r), \
@@ -702,7 +710,9 @@
   $(if $(3),$(eval deps := $(addprefix host_cross_,$(deps))))\
   $(eval r := $(filter $($(root))/%,$(call module-installed-files,\
     $(deps))))\
-  $(eval $(call add-required-deps,$(word 2,$(p)),$(r)))\
+  $(if $(filter $(1),HOST_),\
+    $(eval $(call add-required-host-so-deps,$(word 2,$(p)),$(r))),\
+    $(eval $(call add-required-deps,$(word 2,$(p)),$(r))))\
   $(eval ALL_MODULES.$(mod).REQUIRED += $(deps)))
 endef
 
diff --git a/core/ninja.mk b/core/ninja.mk
index f3aa70e..3779df3 100644
--- a/core/ninja.mk
+++ b/core/ninja.mk
@@ -148,7 +148,7 @@
 .PHONY: ninja_wrapper
 ninja_wrapper: $(COMBINED_BUILD_NINJA) $(MAKEPARALLEL)
 	@echo Starting build with ninja
-	+$(hide) export NINJA_STATUS="$(NINJA_STATUS)" && source $(KATI_ENV_SH) && $(NINJA_MAKEPARALLEL) $(NINJA) $(NINJA_GOALS) -C $(TOP) -f $(COMBINED_BUILD_NINJA) $(NINJA_ARGS)
+	+$(hide) export NINJA_STATUS="$(NINJA_STATUS)" && source $(KATI_ENV_SH) && exec $(NINJA_MAKEPARALLEL) $(NINJA) -d keepdepfile $(NINJA_GOALS) -C $(TOP) -f $(COMBINED_BUILD_NINJA) $(NINJA_ARGS)
 
 # Dummy Android.mk and CleanSpec.mk files so that kati won't recurse into the
 # out directory
diff --git a/core/product_config.mk b/core/product_config.mk
index 0d4ced3..3b8c0eb 100644
--- a/core/product_config.mk
+++ b/core/product_config.mk
@@ -189,6 +189,8 @@
 all_product_configs := $(get-all-product-makefiles)
 endif
 
+all_named_products :=
+
 # Find the product config makefile for the current product.
 # all_product_configs consists items like:
 # <product_name>:<path_to_the_product_makefile>
@@ -202,9 +204,11 @@
     $(eval _cpm_word2 := $(word 2,$(_cpm_words)))\
     $(if $(_cpm_word2),\
         $(eval all_product_makefiles += $(_cpm_word2))\
+        $(eval all_named_products += $(_cpm_word2))\
         $(if $(filter $(TARGET_PRODUCT),$(_cpm_word1)),\
             $(eval current_product_makefile += $(_cpm_word2)),),\
         $(eval all_product_makefiles += $(f))\
+        $(eval all_named_products += $(basename $(notdir $(f))))\
         $(if $(filter $(TARGET_PRODUCT),$(basename $(notdir $(f)))),\
             $(eval current_product_makefile += $(f)),)))
 _cpm_words :=
diff --git a/tools/droiddoc/templates-ndk/assets/css/default.css b/tools/droiddoc/templates-ndk/assets/css/default.css
index f411d93..036c0eb 100644
--- a/tools/droiddoc/templates-ndk/assets/css/default.css
+++ b/tools/droiddoc/templates-ndk/assets/css/default.css
@@ -4217,7 +4217,7 @@
 }
 
 /* offset the <a name=""> tags to account for sticky nav */
-body.reference a[name] {
+body.reference a[name]:empty {
   visibility: hidden;
   display: block;
   position: relative;
diff --git a/tools/droiddoc/templates-sdk-dev/assets/css/default.css b/tools/droiddoc/templates-sdk-dev/assets/css/default.css
index 43449d4..11bbacf 100644
--- a/tools/droiddoc/templates-sdk-dev/assets/css/default.css
+++ b/tools/droiddoc/templates-sdk-dev/assets/css/default.css
@@ -3209,7 +3209,7 @@
 }
 
 /* offset the <a name=""> tags to account for sticky nav */
-body.reference a[name] {
+body.reference a[name]:empty {
   visibility: hidden;
   display: block;
   position: relative;
diff --git a/tools/droiddoc/templates-sdk-refonly/assets/css/default.css b/tools/droiddoc/templates-sdk-refonly/assets/css/default.css
index 106ab2f..d12852a 100644
--- a/tools/droiddoc/templates-sdk-refonly/assets/css/default.css
+++ b/tools/droiddoc/templates-sdk-refonly/assets/css/default.css
@@ -732,7 +732,7 @@
     text-align:center;
     width: 50%;
   }
-  
+
   .training-nav-top a.prev-page-link {
     padding-left: 15px;
     text-align: left;
@@ -840,7 +840,7 @@
     margin: 0 0 6px;
     line-height: 16px;
   }
-  
+
   /* Class colors */
   ol.class-list li:nth-child(10n+1) .title {
     background: #00bcd4;
@@ -872,7 +872,7 @@
   ol.class-list li:nth-child(10n+10) .title {
     background: #7e57c2;
   }
-  
+
   @media (max-width: 719px) {
     ol.class-list ol,
     ol.class-list .description {
@@ -3822,8 +3822,8 @@
   display: none;
 }
 
-/* offset the <a name=""> tags to account for sticky nav */
-body.reference a[name] {
+/* offset the empty <a name=""> tags to account for sticky nav */
+body.reference a[name]:empty {
   visibility: hidden;
   display: block;
   position: relative;
@@ -6376,7 +6376,7 @@
 .dac-button.dac-raised.dac-primary, .landing-secondary, .button {
   background-color: #039bef; }
   .dac-button.dac-raised.dac-primary:hover, .landing-secondary:hover, .button:hover {
-    background-color: #0288d1; 
+    background-color: #0288d1;
     color:#fff; }
   .dac-button.dac-raised.dac-primary:active, .landing-secondary:active, .button:active {
     background-color: #0277bd;
diff --git a/tools/droiddoc/templates-sdk/assets/css/default.css b/tools/droiddoc/templates-sdk/assets/css/default.css
index accf7bf..c71f4f4 100644
--- a/tools/droiddoc/templates-sdk/assets/css/default.css
+++ b/tools/droiddoc/templates-sdk/assets/css/default.css
@@ -3822,15 +3822,14 @@
   display: none;
 }
 
-/* offset the <a name=""> tags to account for sticky nav */
-body.reference a[name] {
+/* offset the empty <a name=""> tags to account for sticky nav */
+body.reference a[name]:empty {
   visibility: hidden;
   display: block;
   position: relative;
   top: -56px;
 }
 
-
 /* Quicknav */
 .btn-quicknav {
   width:20px;
diff --git a/tools/kati_all_products.sh b/tools/kati_all_products.sh
new file mode 100755
index 0000000..4567dbd
--- /dev/null
+++ b/tools/kati_all_products.sh
@@ -0,0 +1,7 @@
+#!/bin/bash -e
+
+cd $ANDROID_BUILD_TOP
+mkdir -p out.kati
+source build/envsetup.sh
+
+get_build_var all_named_products | sed "s/ /\n/g" | parallel "$@" --progress "(source build/envsetup.sh; lunch {}-eng && m -j OUT_DIR=out.kati/{} out.kati/{}/build-{}.ninja) >out.kati/log.{} 2>&1"
diff --git a/tools/makeparallel/makeparallel.cpp b/tools/makeparallel/makeparallel.cpp
index c70fa9a..4ae8f61 100644
--- a/tools/makeparallel/makeparallel.cpp
+++ b/tools/makeparallel/makeparallel.cpp
@@ -337,7 +337,29 @@
 
   args.push_back(nullptr);
 
-  pid_t pid = fork();
+  static pid_t pid;
+
+  // Set up signal handlers to forward SIGHUP, SIGINT, SIGQUIT, SIGTERM, and
+  // SIGALRM to child
+  struct sigaction action = {};
+  action.sa_flags = SA_SIGINFO | SA_RESTART,
+  action.sa_sigaction = [](int signal, siginfo_t*, void*) {
+    if (pid > 0) {
+      kill(pid, signal);
+    }
+  };
+
+  int ret = 0;
+  if (!ret) ret = sigaction(SIGHUP, &action, NULL);
+  if (!ret) ret = sigaction(SIGINT, &action, NULL);
+  if (!ret) ret = sigaction(SIGQUIT, &action, NULL);
+  if (!ret) ret = sigaction(SIGTERM, &action, NULL);
+  if (!ret) ret = sigaction(SIGALRM, &action, NULL);
+  if (ret < 0) {
+    error(errno, errno, "sigaction failed");
+  }
+
+  pid = fork();
   if (pid < 0) {
     error(errno, errno, "fork failed");
   } else if (pid == 0) {
@@ -361,9 +383,10 @@
   }
 
   // parent
+
   siginfo_t status = {};
   int exit_status = 0;
-  int ret = waitid(P_PID, pid, &status, WEXITED);
+  ret = waitid(P_PID, pid, &status, WEXITED);
   if (ret < 0) {
     error(errno, errno, "waitpid failed");
   } else if (status.si_code == CLD_EXITED) {
diff --git a/tools/releasetools/add_img_to_target_files.py b/tools/releasetools/add_img_to_target_files.py
index 8c5dbcf..2e26514 100755
--- a/tools/releasetools/add_img_to_target_files.py
+++ b/tools/releasetools/add_img_to_target_files.py
@@ -96,23 +96,6 @@
   imgname = BuildSystem(OPTIONS.input_tmp, OPTIONS.info_dict,
                         block_list=block_list)
 
-  # AVB: if enabled, calculate and add dm-verity integrity hashes and
-  # metadata to system.img.
-  if OPTIONS.info_dict.get("board_avb_enable", None) == "true":
-    avbtool = os.getenv('AVBTOOL') or "avbtool"
-    part_size = OPTIONS.info_dict.get("system_size", None)
-    cmd = [avbtool, "add_hashtree_footer", "--image", imgname,
-           "--partition_size", str(part_size), "--partition_name", "system"]
-    common.AppendAVBSigningArgs(cmd)
-    args = OPTIONS.info_dict.get("board_avb_system_add_hashtree_footer_args",
-                                 None)
-    if args and args.strip():
-      cmd.extend(shlex.split(args))
-    p = common.Run(cmd, stdout=subprocess.PIPE)
-    p.communicate()
-    assert p.returncode == 0, "avbtool add_hashtree_footer of %s failed" % (
-      os.path.basename(OPTIONS.input_tmp))
-
   common.ZipWrite(output_zip, imgname, prefix + "system.img")
   common.ZipWrite(output_zip, block_list, prefix + "system.map")
   return imgname
diff --git a/tools/releasetools/build_image.py b/tools/releasetools/build_image.py
index a7b3fdd..50e81bf 100755
--- a/tools/releasetools/build_image.py
+++ b/tools/releasetools/build_image.py
@@ -27,6 +27,7 @@
 import sys
 import commands
 import common
+import shlex
 import shutil
 import sparse_img
 import tempfile
@@ -102,6 +103,51 @@
   simg = sparse_img.SparseImage(image_file, mode="r+b", build_map=False)
   simg.AppendFillChunk(0, blocks)
 
+def AVBCalcMaxImageSize(avbtool, partition_size, additional_args):
+  """Calculates max image size for a given partition size.
+
+  Args:
+    avbtool: String with path to avbtool.
+    partition_size: The size of the partition in question.
+    additional_args: Additional arguments to pass to 'avbtool
+      add_hashtree_image'.
+  Returns:
+    The maximum image size or 0 if an error occurred.
+  """
+  cmdline = "%s add_hashtree_footer " % avbtool
+  cmdline += "--partition_size %d " % partition_size
+  cmdline += "--calc_max_image_size "
+  cmdline += additional_args
+  (output, exit_code) = RunCommand(shlex.split(cmdline))
+  if exit_code != 0:
+    return 0
+  else:
+    return int(output)
+
+def AVBAddHashtree(image_path, avbtool, partition_size, partition_name,
+                   signing_args, additional_args):
+  """Adds dm-verity hashtree and AVB metadata to an image.
+
+  Args:
+    image_path: Path to image to modify.
+    avbtool: String with path to avbtool.
+    partition_size: The size of the partition in question.
+    partition_name: The name of the partition - will be embedded in metadata.
+    signing_args: Arguments for signing the image.
+    additional_args: Additional arguments to pass to 'avbtool
+      add_hashtree_image'.
+  Returns:
+    True if the operation succeeded.
+  """
+  cmdline = "%s add_hashtree_footer " % avbtool
+  cmdline += "--partition_size %d " % partition_size
+  cmdline += "--partition_name %s " % partition_name
+  cmdline += "--image %s " % image_path
+  cmdline += signing_args + " "
+  cmdline += additional_args
+  (_, exit_code) = RunCommand(shlex.split(cmdline))
+  return exit_code == 0
+
 def AdjustPartitionSizeForVerity(partition_size, fec_supported):
   """Modifies the provided partition size to account for the verity metadata.
 
@@ -375,6 +421,18 @@
     prop_dict["original_partition_size"] = str(partition_size)
     prop_dict["verity_size"] = str(verity_size)
 
+  # Adjust partition size for AVB.
+  if prop_dict.get("avb_enable") == "true":
+    avbtool = prop_dict.get("avb_avbtool")
+    partition_size = int(prop_dict.get("partition_size"))
+    additional_args = prop_dict["avb_add_hashtree_footer_args"]
+    max_image_size = AVBCalcMaxImageSize(avbtool, partition_size,
+                                         additional_args)
+    if max_image_size == 0:
+      return False
+    prop_dict["partition_size"] = str(max_image_size)
+    prop_dict["original_partition_size"] = str(partition_size)
+
   if fs_type.startswith("ext"):
     build_command = ["mkuserimg.sh"]
     if "extfs_sparse_flag" in prop_dict:
@@ -497,6 +555,17 @@
     if not MakeVerityEnabledImage(out_file, verity_fec_supported, prop_dict):
       return False
 
+  # Add AVB hashtree and metadata.
+  if "avb_enable" in prop_dict:
+    avbtool = prop_dict.get("avb_avbtool")
+    original_partition_size = int(prop_dict.get("original_partition_size"))
+    partition_name = prop_dict["partition_name"]
+    signing_args = prop_dict["avb_signing_args"]
+    additional_args = prop_dict["avb_add_hashtree_footer_args"]
+    if not AVBAddHashtree(out_file, avbtool, original_partition_size,
+                          partition_name, signing_args, additional_args):
+      return False
+
   if run_fsck and prop_dict.get("skip_fsck") != "true":
     success, unsparse_image = UnsparseImage(out_file, replace=False)
     if not success:
@@ -537,7 +606,9 @@
       "verity",
       "verity_key",
       "verity_signer_cmd",
-      "verity_fec"
+      "verity_fec",
+      "avb_signing_args",
+      "avb_avbtool"
       )
   for p in common_props:
     copy_prop(p, p)
@@ -559,6 +630,9 @@
     copy_prop("system_squashfs_compressor_opt", "squashfs_compressor_opt")
     copy_prop("system_squashfs_disable_4k_align", "squashfs_disable_4k_align")
     copy_prop("system_base_fs_file", "base_fs_file")
+    copy_prop("system_avb_enable", "avb_enable")
+    copy_prop("system_avb_add_hashtree_footer_args",
+              "avb_add_hashtree_footer_args")
   elif mount_point == "data":
     # Copy the generic fs type first, override with specific one if available.
     copy_prop("fs_type", "fs_type")
@@ -577,12 +651,15 @@
     copy_prop("vendor_squashfs_compressor_opt", "squashfs_compressor_opt")
     copy_prop("vendor_squashfs_disable_4k_align", "squashfs_disable_4k_align")
     copy_prop("vendor_base_fs_file", "base_fs_file")
+    copy_prop("vendor_avb_enable", "avb_enable")
+    copy_prop("vendor_avb_add_hashtree_footer_args",
+              "avb_add_hashtree_footer_args")
   elif mount_point == "oem":
     copy_prop("fs_type", "fs_type")
     copy_prop("oem_size", "partition_size")
     copy_prop("oem_journal_size", "journal_size")
     copy_prop("has_ext4_reserved_blocks", "has_ext4_reserved_blocks")
-
+  d["partition_name"] = mount_point
   return d
 
 
diff --git a/tools/warn.py b/tools/warn.py
index 4ed4952..ea1cd22 100755
--- a/tools/warn.py
+++ b/tools/warn.py
@@ -109,17 +109,19 @@
   HIGH = 1
   MEDIUM = 2
   LOW = 3
-  TIDY = 4
-  HARMLESS = 5
-  UNKNOWN = 6
-  SKIP = 7
-  range = range(8)
+  ANALYZER = 4
+  TIDY = 5
+  HARMLESS = 6
+  UNKNOWN = 7
+  SKIP = 8
+  range = range(SKIP + 1)
   attributes = [
       # pylint:disable=bad-whitespace
       ['fuchsia',   'FixNow',    'Critical warnings, fix me now'],
       ['red',       'High',      'High severity warnings'],
       ['orange',    'Medium',    'Medium severity warnings'],
       ['yellow',    'Low',       'Low severity warnings'],
+      ['hotpink',   'Analyzer',  'Clang-Analyzer warnings'],
       ['peachpuff', 'Tidy',      'Clang-Tidy warnings'],
       ['limegreen', 'Harmless',  'Harmless warnings'],
       ['lightblue', 'Unknown',   'Unknown warnings'],
@@ -131,6 +133,9 @@
 
 warn_patterns = [
     # pylint:disable=line-too-long,g-inconsistent-quotes
+    {'category': 'C/C++', 'severity': Severity.ANALYZER,
+     'description': 'clang-analyzer Security warning',
+     'patterns': [r".*: warning: .+\[clang-analyzer-security.*\]"]},
     {'category': 'make', 'severity': Severity.MEDIUM,
      'description': 'make: overriding commands/ignoring old commands',
      'patterns': [r".*: warning: overriding commands for target .+",
@@ -1283,8 +1288,8 @@
      'description': 'Comment inside comment',
      'patterns': [r".*: warning: "".+"" within comment"]},
     # Warning "value stored is never read" could be from clang-tidy or clang static analyzer.
-    {'category': 'C/C++', 'severity': Severity.TIDY,
-     'description': 'clang-tidy Value stored is never read',
+    {'category': 'C/C++', 'severity': Severity.ANALYZER,
+     'description': 'clang-analyzer Value stored is never read',
      'patterns': [r".*: warning: Value stored to .+ is never read.*clang-analyzer-deadcode.DeadStores"]},
     {'category': 'C/C++', 'severity': Severity.LOW,
      'description': 'Value stored is never read',
@@ -1601,46 +1606,46 @@
     {'category': 'C/C++', 'severity': Severity.TIDY,
      'description': 'clang-tidy performance-unnecessary-value-param',
      'patterns': [r".*: .+\[performance-unnecessary-value-param\]$"]},
-    {'category': 'C/C++', 'severity': Severity.TIDY,
+    {'category': 'C/C++', 'severity': Severity.ANALYZER,
      'description': 'clang-analyzer Unreachable code',
      'patterns': [r".*: warning: This statement is never executed.*UnreachableCode"]},
-    {'category': 'C/C++', 'severity': Severity.TIDY,
+    {'category': 'C/C++', 'severity': Severity.ANALYZER,
      'description': 'clang-analyzer Size of malloc may overflow',
      'patterns': [r".*: warning: .* size of .* may overflow .*MallocOverflow"]},
-    {'category': 'C/C++', 'severity': Severity.TIDY,
+    {'category': 'C/C++', 'severity': Severity.ANALYZER,
      'description': 'clang-analyzer Stream pointer might be NULL',
      'patterns': [r".*: warning: Stream pointer might be NULL .*unix.Stream"]},
-    {'category': 'C/C++', 'severity': Severity.TIDY,
+    {'category': 'C/C++', 'severity': Severity.ANALYZER,
      'description': 'clang-analyzer Opened file never closed',
      'patterns': [r".*: warning: Opened File never closed.*unix.Stream"]},
-    {'category': 'C/C++', 'severity': Severity.TIDY,
+    {'category': 'C/C++', 'severity': Severity.ANALYZER,
      'description': 'clang-analyzer sozeof() on a pointer type',
      'patterns': [r".*: warning: .*calls sizeof.* on a pointer type.*SizeofPtr"]},
-    {'category': 'C/C++', 'severity': Severity.TIDY,
+    {'category': 'C/C++', 'severity': Severity.ANALYZER,
      'description': 'clang-analyzer Pointer arithmetic on non-array variables',
      'patterns': [r".*: warning: Pointer arithmetic on non-array variables .*PointerArithm"]},
-    {'category': 'C/C++', 'severity': Severity.TIDY,
+    {'category': 'C/C++', 'severity': Severity.ANALYZER,
      'description': 'clang-analyzer Subtraction of pointers of different memory chunks',
      'patterns': [r".*: warning: Subtraction of two pointers .*PointerSub"]},
-    {'category': 'C/C++', 'severity': Severity.TIDY,
+    {'category': 'C/C++', 'severity': Severity.ANALYZER,
      'description': 'clang-analyzer Access out-of-bound array element',
      'patterns': [r".*: warning: Access out-of-bound array element .*ArrayBound"]},
-    {'category': 'C/C++', 'severity': Severity.TIDY,
+    {'category': 'C/C++', 'severity': Severity.ANALYZER,
      'description': 'clang-analyzer Out of bound memory access',
      'patterns': [r".*: warning: Out of bound memory access .*ArrayBoundV2"]},
-    {'category': 'C/C++', 'severity': Severity.TIDY,
+    {'category': 'C/C++', 'severity': Severity.ANALYZER,
      'description': 'clang-analyzer Possible lock order reversal',
      'patterns': [r".*: warning: .* Possible lock order reversal.*PthreadLock"]},
-    {'category': 'C/C++', 'severity': Severity.TIDY,
+    {'category': 'C/C++', 'severity': Severity.ANALYZER,
      'description': 'clang-analyzer Argument is a pointer to uninitialized value',
      'patterns': [r".*: warning: .* argument is a pointer to uninitialized value .*CallAndMessage"]},
-    {'category': 'C/C++', 'severity': Severity.TIDY,
+    {'category': 'C/C++', 'severity': Severity.ANALYZER,
      'description': 'clang-analyzer cast to struct',
      'patterns': [r".*: warning: Casting a non-structure type to a structure type .*CastToStruct"]},
-    {'category': 'C/C++', 'severity': Severity.TIDY,
+    {'category': 'C/C++', 'severity': Severity.ANALYZER,
      'description': 'clang-analyzer call path problems',
      'patterns': [r".*: warning: Call Path : .+"]},
-    {'category': 'C/C++', 'severity': Severity.TIDY,
+    {'category': 'C/C++', 'severity': Severity.ANALYZER,
      'description': 'clang-analyzer other',
      'patterns': [r".*: .+\[clang-analyzer-.+\]$",
                   r".*: Call Path : .+$"]},