Merge "Reduce how often both mutated variants are needed."
diff --git a/cc/sanitize.go b/cc/sanitize.go
index 70aa412..fcea4ef 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -18,6 +18,7 @@
 	"fmt"
 	"io"
 	"strings"
+	"sync"
 
 	"android/soong/android"
 	"android/soong/cc/config"
@@ -36,9 +37,10 @@
 		"-fsanitize-blacklist=external/compiler-rt/lib/cfi/cfi_blacklist.txt"}
 	cfiLdflags = []string{"-flto", "-fsanitize-cfi-cross-dso", "-fsanitize=cfi",
 		"-Wl,-plugin-opt,O1"}
-	cfiArflags        = []string{"--plugin ${config.ClangBin}/../lib64/LLVMgold.so"}
-	cfiExportsMapPath = "build/soong/cc/config/cfi_exports.map"
-	cfiExportsMap     android.Path
+	cfiArflags         = []string{"--plugin ${config.ClangBin}/../lib64/LLVMgold.so"}
+	cfiExportsMapPath  = "build/soong/cc/config/cfi_exports.map"
+	cfiExportsMap      android.Path
+	cfiStaticLibsMutex sync.Mutex
 
 	intOverflowCflags = []string{"-fsanitize-blacklist=build/soong/cc/config/integer_overflow_blacklist.txt"}
 )
@@ -122,6 +124,10 @@
 	androidMkRuntimeLibrary string
 }
 
+func init() {
+	android.RegisterMakeVarsProvider(pctx, cfiMakeVarsProvider)
+}
+
 func (sanitize *sanitize) props() []interface{} {
 	return []interface{}{&sanitize.Properties}
 }
@@ -243,6 +249,12 @@
 		s.Diag.Cfi = nil
 	}
 
+	// Also disable CFI for host builds.
+	if ctx.Host() {
+		s.Cfi = nil
+		s.Diag.Cfi = nil
+	}
+
 	if ctx.staticBinary() {
 		s.Address = nil
 		s.Coverage = nil
@@ -474,12 +486,11 @@
 			fmt.Fprintln(w, "LOCAL_SHARED_LIBRARIES += "+sanitize.androidMkRuntimeLibrary)
 		}
 	})
-	if ctx.Target().Os.Class == android.Device {
-		if Bool(sanitize.Properties.Sanitize.Cfi) {
-			ret.SubName += ".cfi"
-		} else if Bool(sanitize.Properties.Sanitize.Address) {
-			ret.SubName += ".asan"
-		}
+
+	// Add a suffix for CFI-enabled static libraries to allow surfacing both to make without a
+	// name conflict.
+	if ret.Class == "STATIC_LIBRARIES" && Bool(sanitize.Properties.Sanitize.Cfi) {
+		ret.SubName += ".cfi"
 	}
 }
 
@@ -584,27 +595,44 @@
 
 				modules[0].(*Module).sanitize.Properties.SanitizeDep = false
 				modules[1].(*Module).sanitize.Properties.SanitizeDep = false
-				if mctx.Device() {
-					// CFI and ASAN are currently mutually exclusive so disable
-					// CFI if this is an ASAN variant.
-					if t == asan {
+
+				// We don't need both variants active for anything but CFI-enabled
+				// target static libraries, so suppress the appropriate variant in
+				// all other cases.
+				if t == cfi {
+					if c.static() {
+						if !mctx.Device() {
+							if isSanitizerEnabled {
+								modules[0].(*Module).Properties.PreventInstall = true
+								modules[0].(*Module).Properties.HideFromMake = true
+							} else {
+								modules[1].(*Module).Properties.PreventInstall = true
+								modules[1].(*Module).Properties.HideFromMake = true
+							}
+						} else {
+							cfiStaticLibs := cfiStaticLibs(mctx.AConfig())
+
+							cfiStaticLibsMutex.Lock()
+							*cfiStaticLibs = append(*cfiStaticLibs, c.Name())
+							cfiStaticLibsMutex.Unlock()
+						}
+					} else {
+						modules[0].(*Module).Properties.PreventInstall = true
+						modules[0].(*Module).Properties.HideFromMake = true
+					}
+				} else if t == asan {
+					if mctx.Device() {
+						// CFI and ASAN are currently mutually exclusive so disable
+						// CFI if this is an ASAN variant.
 						modules[1].(*Module).sanitize.Properties.InSanitizerDir = true
 						modules[1].(*Module).sanitize.SetSanitizer(cfi, false)
 					}
-				} else {
-					if mctx.AConfig().EmbeddedInMake() {
-						if isSanitizerEnabled {
-							modules[0].(*Module).Properties.HideFromMake = true
-						} else {
-							modules[1].(*Module).Properties.HideFromMake = true
-						}
-					}
-				}
-				if !mctx.AConfig().EmbeddedInMake() || !mctx.Device() {
 					if isSanitizerEnabled {
 						modules[0].(*Module).Properties.PreventInstall = true
+						modules[0].(*Module).Properties.HideFromMake = true
 					} else {
 						modules[1].(*Module).Properties.PreventInstall = true
+						modules[1].(*Module).Properties.HideFromMake = true
 					}
 				}
 			}
@@ -612,3 +640,14 @@
 		}
 	}
 }
+
+func cfiStaticLibs(config android.Config) *[]string {
+	return config.Once("cfiStaticLibs", func() interface{} {
+		return &[]string{}
+	}).(*[]string)
+}
+
+func cfiMakeVarsProvider(ctx android.MakeVarsContext) {
+	cfiStaticLibs := cfiStaticLibs(ctx.Config())
+	ctx.Strict("SOONG_CFI_STATIC_LIBRARIES", strings.Join(*cfiStaticLibs, " "))
+}