Support memtag_heap in SANITIZE_TARGET_DIAG, fix cc_test interation.

cc_test without sanitize:memtag_heap acts as if it has implicit
sanitize{memtag_heap:true, diag:{memtag_heap:true}}. This is unaffected
by SANITIZE_TARGET.

Refactor the test to cover all permutations.

Change memtag include lists to act similar to SANITIZE_TARGET_DIAG: the
the sync include list upgrades async targets to sync, unless diag is
explicitly set to false in the target definition.

Bug: b/135772972
Test: cc_test.go

Change-Id: I6a969f2f5804cd5f47fc4e93a20e3b99ea5fa111
This commit is contained in:
Evgenii Stepanov 2021-01-12 18:28:33 -08:00
parent 324234bd00
commit 04896cae35
2 changed files with 283 additions and 103 deletions

View File

@ -4543,137 +4543,309 @@ func TestAidlFlagsPassedToTheAidlCompiler(t *testing.T) {
} }
} }
func checkHasImplicitDep(t *testing.T, m android.TestingModule, name string) { type MemtagNoteType int
implicits := m.Rule("ld").Implicits
for _, lib := range implicits {
if strings.Contains(lib.Rel(), name) {
return
}
}
t.Errorf("%q is not found in implicit deps of module %q", name, m.Module().(*Module).Name()) const (
} None MemtagNoteType = iota + 1
Sync
Async
)
func checkDoesNotHaveImplicitDep(t *testing.T, m android.TestingModule, name string) { func (t MemtagNoteType) str() string {
implicits := m.Rule("ld").Implicits switch t {
for _, lib := range implicits { case None:
if strings.Contains(lib.Rel(), name) { return "none"
t.Errorf("%q is found in implicit deps of module %q", name, m.Module().(*Module).Name()) case Sync:
} return "sync"
case Async:
return "async"
default:
panic("invalid note type")
} }
} }
func TestSanitizeMemtagHeap(t *testing.T) { func checkHasMemtagNote(t *testing.T, m android.TestingModule, expected MemtagNoteType) {
rootBp := ` note_async := "note_memtag_heap_async"
cc_library_static { note_sync := "note_memtag_heap_sync"
name: "libstatic",
sanitize: { memtag_heap: true },
}
cc_library_shared { found := None
name: "libshared", implicits := m.Rule("ld").Implicits
sanitize: { memtag_heap: true }, for _, lib := range implicits {
if strings.Contains(lib.Rel(), note_async) {
found = Async
break
} else if strings.Contains(lib.Rel(), note_sync) {
found = Sync
break
} }
}
cc_library { if found != expected {
name: "libboth", t.Errorf("Wrong Memtag note in target %q: found %q, expected %q", m.Module().(*Module).Name(), found.str(), expected.str())
sanitize: { memtag_heap: true }, }
} }
cc_binary {
name: "binary",
shared_libs: [ "libshared" ],
static_libs: [ "libstatic" ],
}
cc_binary {
name: "binary_true",
sanitize: { memtag_heap: true },
}
cc_binary {
name: "binary_true_sync",
sanitize: { memtag_heap: true, diag: { memtag_heap: true }, },
}
cc_binary {
name: "binary_false",
sanitize: { memtag_heap: false },
}
func makeMemtagTestConfig(t *testing.T) android.Config {
templateBp := `
cc_test { cc_test {
name: "test", name: "%[1]s_test",
gtest: false, gtest: false,
} }
cc_test { cc_test {
name: "test_true", name: "%[1]s_test_false",
gtest: false,
sanitize: { memtag_heap: true },
}
cc_test {
name: "test_false",
gtest: false, gtest: false,
sanitize: { memtag_heap: false }, sanitize: { memtag_heap: false },
} }
cc_test { cc_test {
name: "test_true_async", name: "%[1]s_test_true",
gtest: false,
sanitize: { memtag_heap: true },
}
cc_test {
name: "%[1]s_test_true_nodiag",
gtest: false, gtest: false,
sanitize: { memtag_heap: true, diag: { memtag_heap: false } }, sanitize: { memtag_heap: true, diag: { memtag_heap: false } },
} }
` cc_test {
name: "%[1]s_test_true_diag",
gtest: false,
sanitize: { memtag_heap: true, diag: { memtag_heap: true } },
}
subdirAsyncBp := `
cc_binary { cc_binary {
name: "binary_async", name: "%[1]s_binary",
} }
`
cc_binary {
subdirSyncBp := ` name: "%[1]s_binary_false",
cc_binary { sanitize: { memtag_heap: false },
name: "binary_sync", }
cc_binary {
name: "%[1]s_binary_true",
sanitize: { memtag_heap: true },
}
cc_binary {
name: "%[1]s_binary_true_nodiag",
sanitize: { memtag_heap: true, diag: { memtag_heap: false } },
}
cc_binary {
name: "%[1]s_binary_true_diag",
sanitize: { memtag_heap: true, diag: { memtag_heap: true } },
} }
` `
subdirDefaultBp := fmt.Sprintf(templateBp, "default")
subdirExcludeBp := fmt.Sprintf(templateBp, "exclude")
subdirSyncBp := fmt.Sprintf(templateBp, "sync")
subdirAsyncBp := fmt.Sprintf(templateBp, "async")
mockFS := map[string][]byte{ mockFS := map[string][]byte{
"subdir_async/Android.bp": []byte(subdirAsyncBp), "subdir_default/Android.bp": []byte(subdirDefaultBp),
"subdir_sync/Android.bp": []byte(subdirSyncBp), "subdir_exclude/Android.bp": []byte(subdirExcludeBp),
"subdir_sync/Android.bp": []byte(subdirSyncBp),
"subdir_async/Android.bp": []byte(subdirAsyncBp),
} }
config := TestConfig(buildDir, android.Android, nil, rootBp, mockFS) return TestConfig(buildDir, android.Android, nil, "", mockFS)
config.TestProductVariables.DeviceVndkVersion = StringPtr("current") }
config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
config.TestProductVariables.MemtagHeapAsyncIncludePaths = []string{"subdir_async"} func TestSanitizeMemtagHeap(t *testing.T) {
variant := "android_arm64_armv8-a"
config := makeMemtagTestConfig(t)
config.TestProductVariables.MemtagHeapExcludePaths = []string{"subdir_exclude"}
config.TestProductVariables.MemtagHeapSyncIncludePaths = []string{"subdir_sync"} config.TestProductVariables.MemtagHeapSyncIncludePaths = []string{"subdir_sync"}
config.TestProductVariables.MemtagHeapAsyncIncludePaths = []string{"subdir_async"}
ctx := CreateTestContext(config) ctx := CreateTestContext(config)
ctx.Register() ctx.Register()
_, errs := ctx.ParseFileList(".", []string{"Android.bp", "subdir_sync/Android.bp", "subdir_async/Android.bp"}) _, errs := ctx.ParseFileList(".", []string{"Android.bp", "subdir_default/Android.bp", "subdir_exclude/Android.bp", "subdir_sync/Android.bp", "subdir_async/Android.bp"})
android.FailIfErrored(t, errs) android.FailIfErrored(t, errs)
_, errs = ctx.PrepareBuildActions(config) _, errs = ctx.PrepareBuildActions(config)
android.FailIfErrored(t, errs) android.FailIfErrored(t, errs)
variant := "android_arm64_armv8-a" checkHasMemtagNote(t, ctx.ModuleForTests("default_test", variant), Sync)
note_async := "note_memtag_heap_async" checkHasMemtagNote(t, ctx.ModuleForTests("default_test_false", variant), None)
note_sync := "note_memtag_heap_sync" checkHasMemtagNote(t, ctx.ModuleForTests("default_test_true", variant), Async)
note_any := "note_memtag_" checkHasMemtagNote(t, ctx.ModuleForTests("default_test_true_nodiag", variant), Async)
checkHasMemtagNote(t, ctx.ModuleForTests("default_test_true_diag", variant), Sync)
checkDoesNotHaveImplicitDep(t, ctx.ModuleForTests("libshared", "android_arm64_armv8-a_shared"), note_any) checkHasMemtagNote(t, ctx.ModuleForTests("default_binary", variant), None)
checkDoesNotHaveImplicitDep(t, ctx.ModuleForTests("libboth", "android_arm64_armv8-a_shared"), note_any) checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_false", variant), None)
checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_true", variant), Async)
checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_true_nodiag", variant), Async)
checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_true_diag", variant), Sync)
checkDoesNotHaveImplicitDep(t, ctx.ModuleForTests("binary", variant), note_any) checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test", variant), Sync)
checkHasImplicitDep(t, ctx.ModuleForTests("binary_true", variant), note_async) checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_false", variant), None)
checkHasImplicitDep(t, ctx.ModuleForTests("binary_true_sync", variant), note_sync) checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_true", variant), Async)
checkDoesNotHaveImplicitDep(t, ctx.ModuleForTests("binary_false", variant), note_any) checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_true_nodiag", variant), Async)
checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_true_diag", variant), Sync)
checkHasImplicitDep(t, ctx.ModuleForTests("test", variant), note_sync) checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary", variant), None)
checkHasImplicitDep(t, ctx.ModuleForTests("test_true", variant), note_async) checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_false", variant), None)
checkDoesNotHaveImplicitDep(t, ctx.ModuleForTests("test_false", variant), note_any) checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_true", variant), Async)
checkHasImplicitDep(t, ctx.ModuleForTests("test_true_async", variant), note_async) checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_true_nodiag", variant), Async)
checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_true_diag", variant), Sync)
checkHasImplicitDep(t, ctx.ModuleForTests("binary_async", variant), note_async) checkHasMemtagNote(t, ctx.ModuleForTests("async_test", variant), Sync)
checkHasImplicitDep(t, ctx.ModuleForTests("binary_sync", variant), note_sync) checkHasMemtagNote(t, ctx.ModuleForTests("async_test_false", variant), None)
checkHasMemtagNote(t, ctx.ModuleForTests("async_test_true", variant), Async)
checkHasMemtagNote(t, ctx.ModuleForTests("async_test_true_nodiag", variant), Async)
checkHasMemtagNote(t, ctx.ModuleForTests("async_test_true_diag", variant), Sync)
checkHasMemtagNote(t, ctx.ModuleForTests("async_binary", variant), Async)
checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_false", variant), None)
checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_true", variant), Async)
checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_true_nodiag", variant), Async)
checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_true_diag", variant), Sync)
checkHasMemtagNote(t, ctx.ModuleForTests("sync_test", variant), Sync)
checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_false", variant), None)
checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_true", variant), Sync)
checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_true_nodiag", variant), Async)
checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_true_diag", variant), Sync)
checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary", variant), Sync)
checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_false", variant), None)
checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_true", variant), Sync)
checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_true_nodiag", variant), Async)
checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_true_diag", variant), Sync)
}
func TestSanitizeMemtagHeapWithSanitizeDevice(t *testing.T) {
variant := "android_arm64_armv8-a"
config := makeMemtagTestConfig(t)
config.TestProductVariables.MemtagHeapExcludePaths = []string{"subdir_exclude"}
config.TestProductVariables.MemtagHeapSyncIncludePaths = []string{"subdir_sync"}
config.TestProductVariables.MemtagHeapAsyncIncludePaths = []string{"subdir_async"}
config.TestProductVariables.SanitizeDevice = []string{"memtag_heap"}
ctx := CreateTestContext(config)
ctx.Register()
_, errs := ctx.ParseFileList(".", []string{"Android.bp", "subdir_default/Android.bp", "subdir_exclude/Android.bp", "subdir_sync/Android.bp", "subdir_async/Android.bp"})
android.FailIfErrored(t, errs)
_, errs = ctx.PrepareBuildActions(config)
android.FailIfErrored(t, errs)
checkHasMemtagNote(t, ctx.ModuleForTests("default_test", variant), Sync)
checkHasMemtagNote(t, ctx.ModuleForTests("default_test_false", variant), None)
checkHasMemtagNote(t, ctx.ModuleForTests("default_test_true", variant), Async)
checkHasMemtagNote(t, ctx.ModuleForTests("default_test_true_nodiag", variant), Async)
checkHasMemtagNote(t, ctx.ModuleForTests("default_test_true_diag", variant), Sync)
checkHasMemtagNote(t, ctx.ModuleForTests("default_binary", variant), Async)
checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_false", variant), None)
checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_true", variant), Async)
checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_true_nodiag", variant), Async)
checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_true_diag", variant), Sync)
checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test", variant), Sync)
checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_false", variant), None)
checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_true", variant), Async)
checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_true_nodiag", variant), Async)
checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_true_diag", variant), Sync)
checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary", variant), None)
checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_false", variant), None)
checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_true", variant), Async)
checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_true_nodiag", variant), Async)
checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_true_diag", variant), Sync)
checkHasMemtagNote(t, ctx.ModuleForTests("async_test", variant), Sync)
checkHasMemtagNote(t, ctx.ModuleForTests("async_test_false", variant), None)
checkHasMemtagNote(t, ctx.ModuleForTests("async_test_true", variant), Async)
checkHasMemtagNote(t, ctx.ModuleForTests("async_test_true_nodiag", variant), Async)
checkHasMemtagNote(t, ctx.ModuleForTests("async_test_true_diag", variant), Sync)
checkHasMemtagNote(t, ctx.ModuleForTests("async_binary", variant), Async)
checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_false", variant), None)
checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_true", variant), Async)
checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_true_nodiag", variant), Async)
checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_true_diag", variant), Sync)
checkHasMemtagNote(t, ctx.ModuleForTests("sync_test", variant), Sync)
checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_false", variant), None)
checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_true", variant), Sync)
checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_true_nodiag", variant), Async)
checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_true_diag", variant), Sync)
checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary", variant), Sync)
checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_false", variant), None)
checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_true", variant), Sync)
checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_true_nodiag", variant), Async)
checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_true_diag", variant), Sync)
}
func TestSanitizeMemtagHeapWithSanitizeDeviceDiag(t *testing.T) {
variant := "android_arm64_armv8-a"
config := makeMemtagTestConfig(t)
config.TestProductVariables.MemtagHeapExcludePaths = []string{"subdir_exclude"}
config.TestProductVariables.MemtagHeapSyncIncludePaths = []string{"subdir_sync"}
config.TestProductVariables.MemtagHeapAsyncIncludePaths = []string{"subdir_async"}
config.TestProductVariables.SanitizeDevice = []string{"memtag_heap"}
config.TestProductVariables.SanitizeDeviceDiag = []string{"memtag_heap"}
ctx := CreateTestContext(config)
ctx.Register()
_, errs := ctx.ParseFileList(".", []string{"Android.bp", "subdir_default/Android.bp", "subdir_exclude/Android.bp", "subdir_sync/Android.bp", "subdir_async/Android.bp"})
android.FailIfErrored(t, errs)
_, errs = ctx.PrepareBuildActions(config)
android.FailIfErrored(t, errs)
checkHasMemtagNote(t, ctx.ModuleForTests("default_test", variant), Sync)
checkHasMemtagNote(t, ctx.ModuleForTests("default_test_false", variant), None)
checkHasMemtagNote(t, ctx.ModuleForTests("default_test_true", variant), Sync)
checkHasMemtagNote(t, ctx.ModuleForTests("default_test_true_nodiag", variant), Async)
checkHasMemtagNote(t, ctx.ModuleForTests("default_test_true_diag", variant), Sync)
checkHasMemtagNote(t, ctx.ModuleForTests("default_binary", variant), Sync)
checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_false", variant), None)
checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_true", variant), Sync)
checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_true_nodiag", variant), Async)
checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_true_diag", variant), Sync)
checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test", variant), Sync)
checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_false", variant), None)
checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_true", variant), Sync)
checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_true_nodiag", variant), Async)
checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_true_diag", variant), Sync)
checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary", variant), None)
checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_false", variant), None)
checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_true", variant), Sync)
checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_true_nodiag", variant), Async)
checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_true_diag", variant), Sync)
checkHasMemtagNote(t, ctx.ModuleForTests("async_test", variant), Sync)
checkHasMemtagNote(t, ctx.ModuleForTests("async_test_false", variant), None)
checkHasMemtagNote(t, ctx.ModuleForTests("async_test_true", variant), Sync)
checkHasMemtagNote(t, ctx.ModuleForTests("async_test_true_nodiag", variant), Async)
checkHasMemtagNote(t, ctx.ModuleForTests("async_test_true_diag", variant), Sync)
checkHasMemtagNote(t, ctx.ModuleForTests("async_binary", variant), Sync)
checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_false", variant), None)
checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_true", variant), Sync)
checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_true_nodiag", variant), Async)
checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_true_diag", variant), Sync)
checkHasMemtagNote(t, ctx.ModuleForTests("sync_test", variant), Sync)
checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_false", variant), None)
checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_true", variant), Sync)
checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_true_nodiag", variant), Async)
checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_true_diag", variant), Sync)
checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary", variant), Sync)
checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_false", variant), None)
checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_true", variant), Sync)
checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_true_nodiag", variant), Async)
checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_true_diag", variant), Sync)
} }

View File

@ -267,6 +267,12 @@ func (sanitize *sanitize) begin(ctx BaseModuleContext) {
return return
} }
// cc_test targets default to SYNC MemTag unless explicitly set to ASYNC (via diag: {memtag_heap}).
if ctx.testBinary() && s.Memtag_heap == nil {
s.Memtag_heap = boolPtr(true)
s.Diag.Memtag_heap = boolPtr(true)
}
var globalSanitizers []string var globalSanitizers []string
var globalSanitizersDiag []string var globalSanitizersDiag []string
@ -358,27 +364,29 @@ func (sanitize *sanitize) begin(ctx BaseModuleContext) {
s.Diag.Cfi = boolPtr(true) s.Diag.Cfi = boolPtr(true)
} }
if found, globalSanitizersDiag = removeFromList("memtag_heap", globalSanitizersDiag); found &&
s.Diag.Memtag_heap == nil && Bool(s.Memtag_heap) {
s.Diag.Memtag_heap = boolPtr(true)
}
if len(globalSanitizersDiag) > 0 { if len(globalSanitizersDiag) > 0 {
ctx.ModuleErrorf("unknown global sanitizer diagnostics option %s", globalSanitizersDiag[0]) ctx.ModuleErrorf("unknown global sanitizer diagnostics option %s", globalSanitizersDiag[0])
} }
} }
// cc_test targets default to SYNC MemTag.
if ctx.testBinary() && s.Memtag_heap == nil {
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) // Enable Memtag for all components in the include paths (for Aarch64 only)
if s.Memtag_heap == nil && ctx.Arch().ArchType == android.Arm64 { if ctx.Arch().ArchType == android.Arm64 {
if ctx.Config().MemtagHeapSyncEnabledForPath(ctx.ModuleDir()) { if ctx.Config().MemtagHeapSyncEnabledForPath(ctx.ModuleDir()) {
s.Memtag_heap = boolPtr(true) if s.Memtag_heap == nil {
s.Diag.Memtag_heap = boolPtr(true) s.Memtag_heap = boolPtr(true)
}
if s.Diag.Memtag_heap == nil {
s.Diag.Memtag_heap = boolPtr(true)
}
} else if ctx.Config().MemtagHeapAsyncEnabledForPath(ctx.ModuleDir()) { } else if ctx.Config().MemtagHeapAsyncEnabledForPath(ctx.ModuleDir()) {
s.Memtag_heap = boolPtr(true) if s.Memtag_heap == nil {
s.Diag.Memtag_heap = boolPtr(false) s.Memtag_heap = boolPtr(true)
}
} }
} }