diff --git a/compiler-rt/include/sanitizer/common_interface_defs.h b/compiler-rt/include/sanitizer/common_interface_defs.h
--- a/compiler-rt/include/sanitizer/common_interface_defs.h
+++ b/compiler-rt/include/sanitizer/common_interface_defs.h
@@ -105,6 +105,33 @@
// simultaneously.
int __sanitizer_acquire_crash_state();
+/// Returns true (one) if memory inside the object may be poisoned.
+///
+/// Proper poisoning could occur, for example, with
+/// __sanitizer_annotate_contiguous_container.
+/// Memory of the object may be poisoned only if:
+/// - sizeof(obj) % ASAN_GRANULARITY == 0
+/// - &obj % ASAN_GRANULARITY == 0
+///
+/// Note: user is responsible for consideration of how
+/// memory is poisoned inside the object, that function
+/// provides a very basic check.
+///
+/// Note: this function is irrelevant for objects
+/// keeping content in external memory buffer like vector .
+/// It is important for cases like std::basic_string with
+/// short string optimization (content is kept in objects memory).
+///
+/// If this function returns true (one) and object of interest is
+/// [a; c), you always can poison [b;c) and keep [a;b)
+/// not poisoned for every b in [a; c).
+///
+/// \param address Address of the object &obj
+/// \param size Size of the object sizeof(obj)
+///
+/// \returns True if memory of the object may be poisoned.
+int __sanitizer_is_annotable(const void *address, const unsigned long size);
+
/// Annotates the current state of a contiguous container, such as
/// std::vector, std::string, or similar.
///
diff --git a/compiler-rt/lib/asan/asan_poisoning.cpp b/compiler-rt/lib/asan/asan_poisoning.cpp
--- a/compiler-rt/lib/asan/asan_poisoning.cpp
+++ b/compiler-rt/lib/asan/asan_poisoning.cpp
@@ -342,6 +342,31 @@
PoisonAlignedStackMemory(addr, size, false);
}
+// Simple check if memory inside the object may be poisoned.
+// User has to make sure that poisoning is possible,
+// that function only provides a basic check.
+// Remember that there are situations when you can poison objects
+// memory even when this function returns false, but
+// you have to know programs structure, and it's not adviced
+// in general.
+//
+// Note: this function is irrelevant for objects
+// keeping content in external memory buffer like vector .
+// It is important for cases like std::basic_string with
+// short string optimization (content is kept in objects memory).
+//
+// If this function returns true (one) and object of
+// interest is [a; c), you always can poison [b;c)
+// and keep [a;b) not poisoned for every b in [a; c).
+int __sanitizer_is_annotable(const void *address_p,
+ const unsigned long size_v) {
+ uptr address = reinterpret_cast(address_p);
+ uptr size = static_cast(size_v);
+ uptr granularity = ASAN_SHADOW_GRANULARITY;
+
+ return IsAligned(size, granularity) && IsAligned(address, granularity);
+}
+
void __sanitizer_annotate_contiguous_container(const void *beg_p,
const void *end_p,
const void *old_mid_p,
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interface.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interface.inc
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interface.inc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interface.inc
@@ -14,6 +14,7 @@
INTERFACE_FUNCTION(__sanitizer_set_report_path)
INTERFACE_FUNCTION(__sanitizer_set_report_fd)
INTERFACE_FUNCTION(__sanitizer_get_report_path)
+INTERFACE_FUNCTION(__sanitizer_is_annotable)
INTERFACE_FUNCTION(__sanitizer_verify_contiguous_container)
INTERFACE_WEAK_FUNCTION(__sanitizer_on_print)
INTERFACE_WEAK_FUNCTION(__sanitizer_report_error_summary)
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_interface_internal.h b/compiler-rt/lib/sanitizer_common/sanitizer_interface_internal.h
--- a/compiler-rt/lib/sanitizer_common/sanitizer_interface_internal.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_interface_internal.h
@@ -72,6 +72,8 @@
const void *__sanitizer_contiguous_container_find_bad_address(const void *beg,
const void *mid,
const void *end);
+SANITIZER_INTERFACE_ATTRIBUTE
+int __sanitizer_is_annotable(const void *address, const unsigned long);
SANITIZER_INTERFACE_ATTRIBUTE
int __sanitizer_get_module_and_offset_for_pc(void *pc, char *module_path,