diff --git a/bp2build/cc_binary_conversion_test.go b/bp2build/cc_binary_conversion_test.go index 8aa2c3ecb..68dc383ff 100644 --- a/bp2build/cc_binary_conversion_test.go +++ b/bp2build/cc_binary_conversion_test.go @@ -789,3 +789,82 @@ func TestCcBinaryWithSyspropSrcsSomeConfigs(t *testing.T) { }, }) } + +func TestCcBinaryWithIntegerOverflowProperty(t *testing.T) { + runCcBinaryTestCase(t, ccBinaryBp2buildTestCase{ + description: "cc_binary with integer overflow property specified", + blueprint: ` +{rule_name} { + name: "foo", + sanitize: { + integer_overflow: true, + }, +}`, + targets: []testBazelTarget{ + {"cc_binary", "foo", AttrNameToString{ + "local_includes": `["."]`, + "features": `["ubsan_integer_overflow"]`, + }}, + }, + }) +} + +func TestCcBinaryWithMiscUndefinedProperty(t *testing.T) { + runCcBinaryTestCase(t, ccBinaryBp2buildTestCase{ + description: "cc_binary with miscellaneous properties specified", + blueprint: ` +{rule_name} { + name: "foo", + sanitize: { + misc_undefined: ["undefined", "nullability"], + }, +}`, + targets: []testBazelTarget{ + {"cc_binary", "foo", AttrNameToString{ + "local_includes": `["."]`, + "features": `[ + "ubsan_undefined", + "ubsan_nullability", + ]`, + }}, + }, + }) +} + +func TestCcBinaryWithUBSanPropertiesArchSpecific(t *testing.T) { + runCcBinaryTestCase(t, ccBinaryBp2buildTestCase{ + description: "cc_binary has correct feature select when UBSan props are specified in arch specific blocks", + blueprint: ` +{rule_name} { + name: "foo", + sanitize: { + misc_undefined: ["undefined", "nullability"], + }, + target: { + android: { + sanitize: { + misc_undefined: ["alignment"], + }, + }, + linux_glibc: { + sanitize: { + integer_overflow: true, + }, + }, + }, +}`, + targets: []testBazelTarget{ + {"cc_binary", "foo", AttrNameToString{ + "local_includes": `["."]`, + "features": `[ + "ubsan_undefined", + "ubsan_nullability", + ] + select({ + "//build/bazel/platforms/os:android": ["ubsan_alignment"], + "//build/bazel/platforms/os:linux": ["ubsan_integer_overflow"], + "//conditions:default": [], + })`, + }}, + }, + }) +} diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go index a1e83d8c9..5feb02e21 100644 --- a/bp2build/cc_library_conversion_test.go +++ b/bp2build/cc_library_conversion_test.go @@ -3691,3 +3691,113 @@ cc_library { }, ) } + +func TestCcLibraryWithIntegerOverflowProperty(t *testing.T) { + runCcLibraryTestCase(t, Bp2buildTestCase{ + Description: "cc_library has correct features when integer_overflow property is provided", + ModuleTypeUnderTest: "cc_library", + ModuleTypeUnderTestFactory: cc.LibraryFactory, + Blueprint: ` +cc_library { + name: "foo", + sanitize: { + integer_overflow: true, + }, +} +`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{ + "features": `["ubsan_integer_overflow"]`, + "local_includes": `["."]`, + }), + MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{ + "features": `["ubsan_integer_overflow"]`, + "local_includes": `["."]`, + }), + }, + }) +} + +func TestCcLibraryWithMiscUndefinedProperty(t *testing.T) { + runCcLibraryTestCase(t, Bp2buildTestCase{ + Description: "cc_library has correct features when misc_undefined property is provided", + ModuleTypeUnderTest: "cc_library", + ModuleTypeUnderTestFactory: cc.LibraryFactory, + Blueprint: ` +cc_library { + name: "foo", + sanitize: { + misc_undefined: ["undefined", "nullability"], + }, +} +`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{ + "features": `[ + "ubsan_undefined", + "ubsan_nullability", + ]`, + "local_includes": `["."]`, + }), + MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{ + "features": `[ + "ubsan_undefined", + "ubsan_nullability", + ]`, + "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", + ModuleTypeUnderTest: "cc_library", + ModuleTypeUnderTestFactory: cc.LibraryFactory, + Blueprint: ` +cc_library { + name: "foo", + sanitize: { + misc_undefined: ["undefined", "nullability"], + }, + target: { + android: { + sanitize: { + misc_undefined: ["alignment"], + }, + }, + linux_glibc: { + sanitize: { + integer_overflow: true, + }, + }, + }, +} +`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{ + "features": `[ + "ubsan_undefined", + "ubsan_nullability", + ] + select({ + "//build/bazel/platforms/os:android": ["ubsan_alignment"], + "//build/bazel/platforms/os:linux": ["ubsan_integer_overflow"], + "//conditions:default": [], + })`, + "local_includes": `["."]`, + }), + MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{ + "features": `[ + "ubsan_undefined", + "ubsan_nullability", + ] + select({ + "//build/bazel/platforms/os:android": ["ubsan_alignment"], + "//build/bazel/platforms/os:linux": ["ubsan_integer_overflow"], + "//conditions:default": [], + })`, + "local_includes": `["."]`, + }), + }, + }) +} diff --git a/bp2build/cc_library_shared_conversion_test.go b/bp2build/cc_library_shared_conversion_test.go index 7e1d1117d..9b01b6f42 100644 --- a/bp2build/cc_library_shared_conversion_test.go +++ b/bp2build/cc_library_shared_conversion_test.go @@ -886,3 +886,85 @@ func TestCcLibrarySharedHeaderAbiChecker(t *testing.T) { }, }) } + +func TestCcLibrarySharedWithIntegerOverflowProperty(t *testing.T) { + runCcLibrarySharedTestCase(t, Bp2buildTestCase{ + Description: "cc_library_shared has correct features when integer_overflow property is provided", + Blueprint: ` +cc_library_shared { + name: "foo", + sanitize: { + integer_overflow: true, + }, +} +`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{ + "features": `["ubsan_integer_overflow"]`, + "local_includes": `["."]`, + }), + }, + }) +} + +func TestCcLibrarySharedWithMiscUndefinedProperty(t *testing.T) { + runCcLibrarySharedTestCase(t, Bp2buildTestCase{ + Description: "cc_library_shared has correct features when misc_undefined property is provided", + Blueprint: ` +cc_library_shared { + name: "foo", + sanitize: { + misc_undefined: ["undefined", "nullability"], + }, +} +`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{ + "features": `[ + "ubsan_undefined", + "ubsan_nullability", + ]`, + "local_includes": `["."]`, + }), + }, + }) +} + +func TestCcLibrarySharedWithUBSanPropertiesArchSpecific(t *testing.T) { + runCcLibrarySharedTestCase(t, Bp2buildTestCase{ + Description: "cc_library_shared has correct feature select when UBSan props are specified in arch specific blocks", + Blueprint: ` +cc_library_shared { + name: "foo", + sanitize: { + misc_undefined: ["undefined", "nullability"], + }, + target: { + android: { + sanitize: { + misc_undefined: ["alignment"], + }, + }, + linux_glibc: { + sanitize: { + integer_overflow: true, + }, + }, + }, +} +`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{ + "features": `[ + "ubsan_undefined", + "ubsan_nullability", + ] + select({ + "//build/bazel/platforms/os:android": ["ubsan_alignment"], + "//build/bazel/platforms/os:linux": ["ubsan_integer_overflow"], + "//conditions:default": [], + })`, + "local_includes": `["."]`, + }), + }, + }) +} diff --git a/bp2build/cc_library_static_conversion_test.go b/bp2build/cc_library_static_conversion_test.go index b47d1f1f1..cac7f9b5e 100644 --- a/bp2build/cc_library_static_conversion_test.go +++ b/bp2build/cc_library_static_conversion_test.go @@ -1723,3 +1723,85 @@ cc_library_static { }, }) } + +func TestCcLibraryStaticWithIntegerOverflowProperty(t *testing.T) { + runCcLibraryStaticTestCase(t, Bp2buildTestCase{ + Description: "cc_library_static has correct features when integer_overflow property is provided", + Blueprint: ` +cc_library_static { + name: "foo", + sanitize: { + integer_overflow: true, + }, +} +`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("cc_library_static", "foo", AttrNameToString{ + "features": `["ubsan_integer_overflow"]`, + "local_includes": `["."]`, + }), + }, + }) +} + +func TestCcLibraryStaticWithMiscUndefinedProperty(t *testing.T) { + runCcLibraryStaticTestCase(t, Bp2buildTestCase{ + Description: "cc_library_static has correct features when misc_undefined property is provided", + Blueprint: ` +cc_library_static { + name: "foo", + sanitize: { + misc_undefined: ["undefined", "nullability"], + }, +} +`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("cc_library_static", "foo", AttrNameToString{ + "features": `[ + "ubsan_undefined", + "ubsan_nullability", + ]`, + "local_includes": `["."]`, + }), + }, + }) +} + +func TestCcLibraryStaticWithUBSanPropertiesArchSpecific(t *testing.T) { + runCcLibraryStaticTestCase(t, Bp2buildTestCase{ + Description: "cc_library_static has correct feature select when UBSan props are specified in arch specific blocks", + Blueprint: ` +cc_library_static { + name: "foo", + sanitize: { + misc_undefined: ["undefined", "nullability"], + }, + target: { + android: { + sanitize: { + misc_undefined: ["alignment"], + }, + }, + linux_glibc: { + sanitize: { + integer_overflow: true, + }, + }, + }, +} +`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("cc_library_static", "foo", AttrNameToString{ + "features": `[ + "ubsan_undefined", + "ubsan_nullability", + ] + select({ + "//build/bazel/platforms/os:android": ["ubsan_alignment"], + "//build/bazel/platforms/os:linux": ["ubsan_integer_overflow"], + "//conditions:default": [], + })`, + "local_includes": `["."]`, + }), + }, + }) +} diff --git a/cc/bp2build.go b/cc/bp2build.go index 6caa85422..d41aa0057 100644 --- a/cc/bp2build.go +++ b/cc/bp2build.go @@ -341,7 +341,7 @@ type baseAttributes struct { compilerAttributes linkerAttributes - // A combination of compilerAttributes.features and linkerAttributes.features + // A combination of compilerAttributes.features and linkerAttributes.features, as well as sanitizer features features bazel.StringListAttribute protoDependency *bazel.LabelAttribute aidlDependency *bazel.LabelAttribute @@ -781,7 +781,7 @@ func bp2BuildParseBaseProps(ctx android.Bp2buildMutatorContext, module *Module) (&linkerAttrs).wholeArchiveDeps.Add(bp2buildCcSysprop(ctx, module.Name(), module.Properties.Min_sdk_version, compilerAttrs.syspropSrcs)) } - features := compilerAttrs.features.Clone().Append(linkerAttrs.features) + features := compilerAttrs.features.Clone().Append(linkerAttrs.features).Append(bp2buildSanitizerFeatures(ctx, module)) features.DeduplicateAxesFromBase() return baseAttributes{ @@ -1364,3 +1364,20 @@ func bp2buildBinaryLinkerProps(ctx android.BazelConversionPathContext, m *Module return attrs } + +func bp2buildSanitizerFeatures(ctx android.BazelConversionPathContext, m *Module) bazel.StringListAttribute { + sanitizerFeatures := bazel.StringListAttribute{} + bp2BuildPropParseHelper(ctx, m, &SanitizeProperties{}, func(axis bazel.ConfigurationAxis, config string, props interface{}) { + var features []string + if sanitizerProps, ok := props.(*SanitizeProperties); ok { + if sanitizerProps.Sanitize.Integer_overflow != nil && *sanitizerProps.Sanitize.Integer_overflow { + features = append(features, "ubsan_integer_overflow") + } + for _, sanitizer := range sanitizerProps.Sanitize.Misc_undefined { + features = append(features, "ubsan_"+sanitizer) + } + sanitizerFeatures.SetSelectValue(axis, config, features) + } + }) + return sanitizerFeatures +} diff --git a/cc/cc.go b/cc/cc.go index 2ff5bbacc..e07edeb14 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -1859,7 +1859,11 @@ func (c *Module) QueueBazelCall(ctx android.BaseModuleContext) { } func (c *Module) IsMixedBuildSupported(ctx android.BaseModuleContext) bool { - return c.bazelHandler != nil + // TODO(b/261058727): Remove this (enable mised builds for modules with UBSan) + ubsanEnabled := c.sanitize != nil && + ((c.sanitize.Properties.Sanitize.Integer_overflow != nil && *c.sanitize.Properties.Sanitize.Integer_overflow) || + c.sanitize.Properties.Sanitize.Misc_undefined != nil) + return c.bazelHandler != nil && !ubsanEnabled } func (c *Module) ProcessBazelQueryResponse(ctx android.ModuleContext) {