Bp2build Sanitizer Blocklist

Bug: 286894426
Test: Unit tests
Change-Id: I382e028410a185a5017dba1fc47c83ad5b2432cf
diff --git a/bp2build/cc_binary_conversion_test.go b/bp2build/cc_binary_conversion_test.go
index d37722b..f89d42c 100644
--- a/bp2build/cc_binary_conversion_test.go
+++ b/bp2build/cc_binary_conversion_test.go
@@ -868,6 +868,25 @@
 	})
 }
 
+func TestCcBinaryWithSanitizerBlocklist(t *testing.T) {
+	runCcBinaryTestCase(t, ccBinaryBp2buildTestCase{
+		description: "cc_binary has the correct feature when sanitize.blocklist is provided",
+		blueprint: `
+{rule_name} {
+	name: "foo",
+	sanitize: {
+		blocklist: "foo_blocklist.txt",
+	},
+}`,
+		targets: []testBazelTarget{
+			{"cc_binary", "foo", AttrNameToString{
+				"local_includes": `["."]`,
+				"features":       `["ubsan_blocklist_foo_blocklist_txt"]`,
+			}},
+		},
+	})
+}
+
 func TestCcBinaryWithThinLto(t *testing.T) {
 	runCcBinaryTestCase(t, ccBinaryBp2buildTestCase{
 		description: "cc_binary has correct features when thin LTO is enabled",
diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go
index 20f3bf6..24e91f5 100644
--- a/bp2build/cc_library_conversion_test.go
+++ b/bp2build/cc_library_conversion_test.go
@@ -4179,6 +4179,32 @@
 	})
 }
 
+func TestCcLibraryWithSanitizerBlocklist(t *testing.T) {
+	runCcLibraryTestCase(t, Bp2buildTestCase{
+		Description:                "cc_library has correct feature when sanitize.blocklist is provided",
+		ModuleTypeUnderTest:        "cc_library",
+		ModuleTypeUnderTestFactory: cc.LibraryFactory,
+		Blueprint: `
+cc_library {
+		name: "foo",
+		sanitize: {
+			blocklist: "foo_blocklist.txt",
+		},
+}
+`,
+		ExpectedBazelTargets: []string{
+			MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
+				"features":       `["ubsan_blocklist_foo_blocklist_txt"]`,
+				"local_includes": `["."]`,
+			}),
+			MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
+				"features":       `["ubsan_blocklist_foo_blocklist_txt"]`,
+				"local_includes": `["."]`,
+			}),
+		},
+	})
+}
+
 func TestCcLibraryWithUBSanPropertiesArchSpecific(t *testing.T) {
 	runCcLibraryTestCase(t, Bp2buildTestCase{
 		Description:                "cc_library has correct feature select when UBSan props are specified in arch specific blocks",
diff --git a/bp2build/cc_library_shared_conversion_test.go b/bp2build/cc_library_shared_conversion_test.go
index 7f0ba44..a828855 100644
--- a/bp2build/cc_library_shared_conversion_test.go
+++ b/bp2build/cc_library_shared_conversion_test.go
@@ -1212,6 +1212,26 @@
 	})
 }
 
+func TestCcLibrarySharedWithSanitizerBlocklist(t *testing.T) {
+	runCcLibrarySharedTestCase(t, Bp2buildTestCase{
+		Description: "cc_library_shared has correct features when sanitize.blocklist is provided",
+		Blueprint: `
+cc_library_shared {
+	name: "foo",
+	sanitize: {
+		blocklist: "foo_blocklist.txt",
+	},
+}
+`,
+		ExpectedBazelTargets: []string{
+			MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
+				"features":       `["ubsan_blocklist_foo_blocklist_txt"]`,
+				"local_includes": `["."]`,
+			}),
+		},
+	})
+}
+
 func TestCcLibrarySharedWithThinLto(t *testing.T) {
 	runCcLibrarySharedTestCase(t, Bp2buildTestCase{
 		Description: "cc_library_shared has correct features when thin lto is enabled",
diff --git a/bp2build/cc_library_static_conversion_test.go b/bp2build/cc_library_static_conversion_test.go
index f537871..afe76e5 100644
--- a/bp2build/cc_library_static_conversion_test.go
+++ b/bp2build/cc_library_static_conversion_test.go
@@ -1905,6 +1905,26 @@
 	})
 }
 
+func TestCcLibraryStaticWithSanitizerBlocklist(t *testing.T) {
+	runCcLibraryStaticTestCase(t, Bp2buildTestCase{
+		Description: "cc_library_static has correct features when sanitize.blocklist is provided",
+		Blueprint: `
+cc_library_static {
+	name: "foo",
+	sanitize: {
+		blocklist: "foo_blocklist.txt",
+	},
+}
+`,
+		ExpectedBazelTargets: []string{
+			MakeBazelTarget("cc_library_static", "foo", AttrNameToString{
+				"features":       `["ubsan_blocklist_foo_blocklist_txt"]`,
+				"local_includes": `["."]`,
+			}),
+		},
+	})
+}
+
 func TestCcLibraryStaticWithThinLto(t *testing.T) {
 	runCcLibraryStaticTestCase(t, Bp2buildTestCase{
 		Description: "cc_library_static has correct features when thin lto is enabled",
diff --git a/cc/bp2build.go b/cc/bp2build.go
index 1e83ca3..eb91898 100644
--- a/cc/bp2build.go
+++ b/cc/bp2build.go
@@ -1781,6 +1781,12 @@
 			for _, sanitizer := range sanitizerProps.Sanitize.Misc_undefined {
 				features = append(features, "ubsan_"+sanitizer)
 			}
+			blocklist := sanitizerProps.Sanitize.Blocklist
+			if blocklist != nil {
+				// Format the blocklist name to be used in a feature name
+				blocklistFeatureSuffix := strings.Replace(strings.ToLower(*blocklist), ".", "_", -1)
+				features = append(features, "ubsan_blocklist_"+blocklistFeatureSuffix)
+			}
 			if proptools.Bool(sanitizerProps.Sanitize.Cfi) {
 				features = append(features, "android_cfi")
 				if proptools.Bool(sanitizerProps.Sanitize.Config.Cfi_assembly_support) {
diff --git a/cc/cc.go b/cc/cc.go
index f2c8525..fe85cae 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -1930,7 +1930,6 @@
 		sanitizeProps.Safestack,
 		sanitizeProps.Scudo,
 		BoolPtr(len(c.sanitize.Properties.Sanitize.Recover) > 0),
-		BoolPtr(c.sanitize.Properties.Sanitize.Blocklist != nil),
 	}
 	for _, san := range unsupportedSanitizers {
 		if Bool(san) {
diff --git a/cc/sanitize.go b/cc/sanitize.go
index a5691ee..d391cf5 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -62,12 +62,14 @@
 		"-fast-isel=false",
 	}
 
+	sanitizeIgnorelistPrefix = "-fsanitize-ignorelist="
+
 	cfiBlocklistPath     = "external/compiler-rt/lib/cfi"
 	cfiBlocklistFilename = "cfi_blocklist.txt"
 	cfiEnableFlag        = "-fsanitize=cfi"
 	cfiCrossDsoFlag      = "-fsanitize-cfi-cross-dso"
 	cfiCflags            = []string{"-flto", cfiCrossDsoFlag,
-		"-fsanitize-ignorelist=" + cfiBlocklistPath + "/" + cfiBlocklistFilename}
+		sanitizeIgnorelistPrefix + cfiBlocklistPath + "/" + cfiBlocklistFilename}
 	// -flto and -fvisibility are required by clang when -fsanitize=cfi is
 	// used, but have no effect on assembly files
 	cfiAsflags = []string{"-flto", "-fvisibility=default"}
@@ -401,6 +403,7 @@
 	exportedVars.ExportStringList("CfiLdFlags", cfiLdflags[2:])
 	exportedVars.ExportStringList("CfiAsFlags", cfiAsflags[1:])
 
+	exportedVars.ExportString("SanitizeIgnorelistPrefix", sanitizeIgnorelistPrefix)
 	exportedVars.ExportString("CfiCrossDsoFlag", cfiCrossDsoFlag)
 	exportedVars.ExportString("CfiBlocklistPath", cfiBlocklistPath)
 	exportedVars.ExportString("CfiBlocklistFilename", cfiBlocklistFilename)
@@ -965,7 +968,7 @@
 
 	blocklist := android.OptionalPathForModuleSrc(ctx, s.Properties.Sanitize.Blocklist)
 	if blocklist.Valid() {
-		flags.Local.CFlags = append(flags.Local.CFlags, "-fsanitize-ignorelist="+blocklist.String())
+		flags.Local.CFlags = append(flags.Local.CFlags, sanitizeIgnorelistPrefix+blocklist.String())
 		flags.CFlagsDeps = append(flags.CFlagsDeps, blocklist.Path())
 	}
 
diff --git a/tests/lib.sh b/tests/lib.sh
index 7f3970e..b5dea99 100644
--- a/tests/lib.sh
+++ b/tests/lib.sh
@@ -101,6 +101,19 @@
   symlink_directory external/spdx-tools
   symlink_directory libcore
 
+  # TODO: b/286872909 - Remove these when the blocking bug is completed
+  symlink_directory external/libavc
+  symlink_directory external/libaom
+  symlink_directory external/libvpx
+  symlink_directory frameworks/base/libs/androidfw
+  symlink_directory external/libhevc
+  symlink_directory external/libexif
+  symlink_directory external/libopus
+  symlink_directory external/libmpeg2
+  symlink_directory external/expat
+  symlink_directory external/flac
+  symlink_directory system/extras/toolchain-extras
+
   touch "$MOCK_TOP/Android.bp"
 }