Include/exclude lists for memtag_heap sanitizer.

Bug: b/135772972
Test: cc_test.go / TestSanitizeMemtagHeap
Change-Id: I263b23647f1874ae3024101dce1b07091c1c9403
diff --git a/cc/cc_test.go b/cc/cc_test.go
index 1ab1b82..ad9814c 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -4483,7 +4483,7 @@
 }
 
 func TestSanitizeMemtagHeap(t *testing.T) {
-	ctx := testCc(t, `
+	rootBp := `
 		cc_library_static {
 			name: "libstatic",
 			sanitize: { memtag_heap: true },
@@ -4543,7 +4543,37 @@
 			sanitize: { memtag_heap: true, diag: { memtag_heap: false }  },
 		}
 
-		`)
+		`
+
+	subdirAsyncBp := `
+		cc_binary {
+			name: "binary_async",
+		}
+		`
+
+	subdirSyncBp := `
+		cc_binary {
+			name: "binary_sync",
+		}
+		`
+
+	mockFS := map[string][]byte{
+		"subdir_async/Android.bp": []byte(subdirAsyncBp),
+		"subdir_sync/Android.bp":  []byte(subdirSyncBp),
+	}
+
+	config := TestConfig(buildDir, android.Android, nil, rootBp, mockFS)
+	config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
+	config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
+	config.TestProductVariables.MemtagHeapAsyncIncludePaths = []string{"subdir_async"}
+	config.TestProductVariables.MemtagHeapSyncIncludePaths = []string{"subdir_sync"}
+	ctx := CreateTestContext(config)
+	ctx.Register()
+
+	_, errs := ctx.ParseFileList(".", []string{"Android.bp", "subdir_sync/Android.bp", "subdir_async/Android.bp"})
+	android.FailIfErrored(t, errs)
+	_, errs = ctx.PrepareBuildActions(config)
+	android.FailIfErrored(t, errs)
 
 	variant := "android_arm64_armv8-a"
 	note_async := "note_memtag_heap_async"
@@ -4562,4 +4592,7 @@
 	checkHasImplicitDep(t, ctx.ModuleForTests("test_true", variant), note_async)
 	checkDoesNotHaveImplicitDep(t, ctx.ModuleForTests("test_false", variant), note_any)
 	checkHasImplicitDep(t, ctx.ModuleForTests("test_true_async", variant), note_async)
+
+	checkHasImplicitDep(t, ctx.ModuleForTests("binary_async", variant), note_async)
+	checkHasImplicitDep(t, ctx.ModuleForTests("binary_sync", variant), note_sync)
 }
diff --git a/cc/sanitize.go b/cc/sanitize.go
index 13e1780..af17490 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -338,7 +338,9 @@
 			s.Writeonly = boolPtr(true)
 		}
 		if found, globalSanitizers = removeFromList("memtag_heap", globalSanitizers); found && s.Memtag_heap == nil {
-			s.Memtag_heap = boolPtr(true)
+			if !ctx.Config().MemtagHeapDisabledForPath(ctx.ModuleDir()) {
+				s.Memtag_heap = boolPtr(true)
+			}
 		}
 
 		if len(globalSanitizers) > 0 {
@@ -363,8 +365,21 @@
 
 	// cc_test targets default to SYNC MemTag.
 	if ctx.testBinary() && s.Memtag_heap == nil {
-		s.Memtag_heap = boolPtr(true)
-		s.Diag.Memtag_heap = boolPtr(true)
+		if !ctx.Config().MemtagHeapDisabledForPath(ctx.ModuleDir()) {
+			s.Memtag_heap = boolPtr(true)
+			s.Diag.Memtag_heap = boolPtr(true)
+		}
+	}
+
+	// Enable Memtag for all components in the include paths (for Aarch64 only)
+	if s.Memtag_heap == nil && ctx.Arch().ArchType == android.Arm64 {
+		if ctx.Config().MemtagHeapSyncEnabledForPath(ctx.ModuleDir()) {
+			s.Memtag_heap = boolPtr(true)
+			s.Diag.Memtag_heap = boolPtr(true)
+		} else if ctx.Config().MemtagHeapAsyncEnabledForPath(ctx.ModuleDir()) {
+			s.Memtag_heap = boolPtr(true)
+			s.Diag.Memtag_heap = boolPtr(false)
+		}
 	}
 
 	// Enable CFI for all components in the include paths (for Aarch64 only)