From 62e7af299c70fde2c6410ee58ef6fc0f1dc3c25e Mon Sep 17 00:00:00 2001 From: Amy Wishnousky Date: Fri, 3 Apr 2026 14:44:47 -0700 Subject: [PATCH 1/8] Remove stl_asan.lib as a dependency so that annotations can be activated piecemeal. The lib is retained for compatibility with static libraries built with old headers. --- .../__msvc_sanitizer_annotate_container.hpp | 6 +-- stl/src/asan.cpp | 6 +-- tests/std/test.lst | 1 + .../GH_006186_asan_annotate_partial/env.lst | 41 +++++++++++++++++++ .../GH_006186_asan_annotate_partial/test.cpp | 37 +++++++++++++++++ 5 files changed, 85 insertions(+), 6 deletions(-) create mode 100644 tests/std/tests/GH_006186_asan_annotate_partial/env.lst create mode 100644 tests/std/tests/GH_006186_asan_annotate_partial/test.cpp diff --git a/stl/inc/__msvc_sanitizer_annotate_container.hpp b/stl/inc/__msvc_sanitizer_annotate_container.hpp index dbfd83b311d..042f053ac6f 100644 --- a/stl/inc/__msvc_sanitizer_annotate_container.hpp +++ b/stl/inc/__msvc_sanitizer_annotate_container.hpp @@ -129,15 +129,15 @@ _STL_DISABLE_CLANG_WARNINGS #endif // ^^^ !defined(_INSERT_OPTIONAL_ANNOTATION) ^^^ #ifdef _ACTIVATE_STRING_ANNOTATION -#pragma comment(lib, "stl_asan") +extern "C" __declspec(selectany) const bool _Asan_string_should_annotate = true; #pragma detect_mismatch("annotate_string", "1") #endif // ^^^ defined(_ACTIVATE_STRING_ANNOTATION) ^^^ #ifdef _ACTIVATE_VECTOR_ANNOTATION -#pragma comment(lib, "stl_asan") +extern "C" __declspec(selectany) const bool _Asan_vector_should_annotate = true; #pragma detect_mismatch("annotate_vector", "1") #endif // ^^^ defined(_ACTIVATE_VECTOR_ANNOTATION) ^^^ #ifdef _ACTIVATE_OPTIONAL_ANNOTATION -#pragma comment(lib, "stl_asan") +extern "C" __declspec(selectany) const bool _Asan_optional_should_annotate = true; #pragma detect_mismatch("annotate_optional", "1") #endif // ^^^ defined(_ACTIVATE_OPTIONAL_ANNOTATION) ^^^ diff --git a/stl/src/asan.cpp b/stl/src/asan.cpp index e49b05f27f6..360cb01725b 100644 --- a/stl/src/asan.cpp +++ b/stl/src/asan.cpp @@ -3,8 +3,8 @@ namespace std { extern "C" { - extern const bool _Asan_string_should_annotate = true; - extern const bool _Asan_vector_should_annotate = true; - extern const bool _Asan_optional_should_annotate = true; + extern __declspec(selectany) const bool _Asan_string_should_annotate = true; + extern __declspec(selectany) const bool _Asan_vector_should_annotate = true; + extern __declspec(selectany) const bool _Asan_optional_should_annotate = true; } // extern "C" } // namespace std diff --git a/tests/std/test.lst b/tests/std/test.lst index 74cfcda8f4f..588ba0bd946 100644 --- a/tests/std/test.lst +++ b/tests/std/test.lst @@ -282,6 +282,7 @@ tests\GH_005800_stable_sort_large_alignment tests\GH_005816_numeric_limits_traps tests\GH_005968_headers_provide_begin_end tests\GH_005974_asan_annotate_optional +tests\GH_006186_asan_annotate_partial tests\LWG2381_num_get_floating_point tests\LWG2510_tag_classes tests\LWG2597_complex_branch_cut diff --git a/tests/std/tests/GH_006186_asan_annotate_partial/env.lst b/tests/std/tests/GH_006186_asan_annotate_partial/env.lst new file mode 100644 index 00000000000..d5adb5844f3 --- /dev/null +++ b/tests/std/tests/GH_006186_asan_annotate_partial/env.lst @@ -0,0 +1,41 @@ +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +# This test matrix is the usual test matrix, with all currently unsupported options removed, crossed with the ASan flags. + +# TRANSITION, google/sanitizers#328: clang-cl does not support /MDd or /MTd with ASan +RUNALL_INCLUDE ..\prefix.lst +RUNALL_CROSSLIST +PM_CL="/fsanitize=address /DTEST_ENSURE_VECTOR_ENABLED /DTEST_ENSURE_STRING_ENABLED /DTEST_ENSURE_OPTIONAL_ENABLED" +PM_CL="/fsanitize=address /D_DISABLE_VECTOR_ANNOTATION /DTEST_ENSURE_STRING_ENABLED /DTEST_ENSURE_OPTIONAL_ENABLED" +PM_CL="/fsanitize=address /DTEST_ENSURE_VECTOR_ENABLED /D_DISABLE_STRING_ANNOTATION /DTEST_ENSURE_OPTIONAL_ENABLED" +PM_CL="/fsanitize=address /DTEST_ENSURE_VECTOR_ENABLED /DTEST_ENSURE_STRING_ENABLED /D_DISABLE_OPTIONAL_ANNOTATION" +PM_CL="/D_ANNOTATE_STL" +RUNALL_CROSSLIST +PM_CL="/Zi /wd4611 /w14640 /Zc:threadSafeInit-" PM_LINK="/debug" +RUNALL_CROSSLIST +PM_CL="/BE /c /EHsc /MD /std:c++14" +PM_CL="/BE /c /EHsc /MDd /std:c++17 /permissive-" +PM_CL="/BE /c /EHsc /MT /std:c++20 /permissive-" +PM_CL="/BE /c /EHsc /MTd /std:c++latest /permissive-" +PM_CL="/EHsc /MD /std:c++14" +PM_CL="/EHsc /MD /std:c++17" +PM_CL="/EHsc /MD /std:c++20" +PM_CL="/EHsc /MD /std:c++latest /permissive- /Zc:char8_t- /Zc:preprocessor" +PM_CL="/EHsc /MD /std:c++latest /permissive- /Zc:noexceptTypes-" +PM_CL="/EHsc /MDd /std:c++14 /fp:except /Zc:preprocessor" +PM_CL="/EHsc /MDd /std:c++17 /permissive-" +PM_CL="/EHsc /MDd /std:c++20 /permissive-" +PM_CL="/EHsc /MDd /std:c++latest /permissive- /Zc:wchar_t-" +PM_CL="/EHsc /MDd /std:c++latest /permissive-" +PM_CL="/EHsc /MT /std:c++latest /permissive- /analyze:only /analyze:autolog-" +PM_CL="/EHsc /MT /std:c++latest /permissive-" +PM_CL="/EHsc /MTd /std:c++latest /permissive" +PM_CL="/EHsc /MTd /std:c++latest /permissive- /analyze:only /analyze:autolog-" +PM_CL="/EHsc /MTd /std:c++latest /permissive- /fp:strict" +PM_CL="/EHsc /MTd /std:c++latest /permissive-" +# TRANSITION, we don't use /ALTERNATENAME for Clang (see GH-5224) so we cannot test /D_ANNOTATE_VECTOR without -fsanitize=address +PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MD /std:c++14" +PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MD /std:c++17" +PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MT /std:c++20 /permissive-" +PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MT /std:c++latest /permissive- /fp:strict" diff --git a/tests/std/tests/GH_006186_asan_annotate_partial/test.cpp b/tests/std/tests/GH_006186_asan_annotate_partial/test.cpp new file mode 100644 index 00000000000..55483ef1cc1 --- /dev/null +++ b/tests/std/tests/GH_006186_asan_annotate_partial/test.cpp @@ -0,0 +1,37 @@ +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// REQUIRES: x64 || x86 || arm64 + +#if defined(__clang__) && defined(_M_ARM64) // TRANSITION, LLVM-184902, fixed in Clang 23 +#pragma comment(linker, "/INFERASANLIBS") +int main() {} +#else // ^^^ workaround / no workaround vvv + +#include +#include // include __msvc_sanitizer_annotate_container.hpp + +extern "C" const bool _Asan_vector_should_annotate; +extern "C" const bool _Asan_string_should_annotate; +extern "C" const bool _Asan_optional_should_annotate; + +int main() { +#ifdef TEST_ENSURE_VECTOR_ENABLED + assert(_Asan_vector_should_annotate == true); +#else + assert(_Asan_vector_should_annotate == false); +#endif + +#ifdef TEST_ENSURE_STRING_ENABLED + assert(_Asan_string_should_annotate == true); +#else + assert(_Asan_string_should_annotate == false); +#endif + +#ifdef TEST_ENSURE_OPTIONAL_ENABLED + assert(_Asan_optional_should_annotate == true); +#else + assert(_Asan_optional_should_annotate == false); +#endif +} + +#endif // ^^^ no workaround ^^^ From d1baeacbf305bdca36f99c37881d52eacc73b84f Mon Sep 17 00:00:00 2001 From: Amy Wishnousky Date: Fri, 3 Apr 2026 14:53:53 -0700 Subject: [PATCH 2/8] Add comments to stl_asan.lib definitions. --- stl/src/asan.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/stl/src/asan.cpp b/stl/src/asan.cpp index 360cb01725b..6921d52b3bf 100644 --- a/stl/src/asan.cpp +++ b/stl/src/asan.cpp @@ -3,6 +3,11 @@ namespace std { extern "C" { + // Retained for compatibility with old headers that add stl_asan.lib to the link. + // Use __declspec(selectany) to be compatible with new version that define these + // variables as __declspec(selectany) in __msvc_sanitizer_annotate_container.hpp. + // The new method is preferred because previously enabling just string would also + // enable vector and optional. extern __declspec(selectany) const bool _Asan_string_should_annotate = true; extern __declspec(selectany) const bool _Asan_vector_should_annotate = true; extern __declspec(selectany) const bool _Asan_optional_should_annotate = true; From fc4fbf688b389ab660804d4aa2387e522b3d66e2 Mon Sep 17 00:00:00 2001 From: Amy Wishnousky Date: Mon, 13 Apr 2026 16:07:32 -0700 Subject: [PATCH 3/8] Responding to feedback. Update __msvc_sanitizer_annotate_container.hpp to use extern C scope instead of specifier. Update comment in asan.cpp. Remove copy-pasted comment from GH_006186*\env.lst. Fix whitespace in GH_006186*\test.cpp. --- stl/inc/__msvc_sanitizer_annotate_container.hpp | 8 ++++---- stl/src/asan.cpp | 11 ++++++----- .../std/tests/GH_006186_asan_annotate_partial/env.lst | 1 - .../tests/GH_006186_asan_annotate_partial/test.cpp | 1 + 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/stl/inc/__msvc_sanitizer_annotate_container.hpp b/stl/inc/__msvc_sanitizer_annotate_container.hpp index 042f053ac6f..1c3f2e786a8 100644 --- a/stl/inc/__msvc_sanitizer_annotate_container.hpp +++ b/stl/inc/__msvc_sanitizer_annotate_container.hpp @@ -128,16 +128,17 @@ _STL_DISABLE_CLANG_WARNINGS #pragma detect_mismatch("annotate_optional", "0") #endif // ^^^ !defined(_INSERT_OPTIONAL_ANNOTATION) ^^^ +extern "C" { #ifdef _ACTIVATE_STRING_ANNOTATION -extern "C" __declspec(selectany) const bool _Asan_string_should_annotate = true; +__declspec(selectany) const bool _Asan_string_should_annotate = true; #pragma detect_mismatch("annotate_string", "1") #endif // ^^^ defined(_ACTIVATE_STRING_ANNOTATION) ^^^ #ifdef _ACTIVATE_VECTOR_ANNOTATION -extern "C" __declspec(selectany) const bool _Asan_vector_should_annotate = true; +__declspec(selectany) const bool _Asan_vector_should_annotate = true; #pragma detect_mismatch("annotate_vector", "1") #endif // ^^^ defined(_ACTIVATE_VECTOR_ANNOTATION) ^^^ #ifdef _ACTIVATE_OPTIONAL_ANNOTATION -extern "C" __declspec(selectany) const bool _Asan_optional_should_annotate = true; +__declspec(selectany) const bool _Asan_optional_should_annotate = true; #pragma detect_mismatch("annotate_optional", "1") #endif // ^^^ defined(_ACTIVATE_OPTIONAL_ANNOTATION) ^^^ @@ -145,7 +146,6 @@ extern "C" __declspec(selectany) const bool _Asan_optional_should_annotate = tru #undef _ACTIVATE_VECTOR_ANNOTATION #undef _ACTIVATE_OPTIONAL_ANNOTATION -extern "C" { #ifdef _INSERT_VECTOR_ANNOTATION extern const bool _Asan_vector_should_annotate; #endif diff --git a/stl/src/asan.cpp b/stl/src/asan.cpp index 6921d52b3bf..4c8e40d70a6 100644 --- a/stl/src/asan.cpp +++ b/stl/src/asan.cpp @@ -3,11 +3,12 @@ namespace std { extern "C" { - // Retained for compatibility with old headers that add stl_asan.lib to the link. - // Use __declspec(selectany) to be compatible with new version that define these - // variables as __declspec(selectany) in __msvc_sanitizer_annotate_container.hpp. - // The new method is preferred because previously enabling just string would also - // enable vector and optional. + // TRANSITION, ABI: preserved for compatibility with old headers, which + // added stl_asan.lib to the link line. We use __declspec(selectany) to be + // compatible with the new headers that defines these variables as + // __declspec(selectany) in __msvc_sanitizer_annotate_container.hpp. + // The new method is preferred because previously enabling just string + // would also enable vector and optional. See GH-6186 for details. extern __declspec(selectany) const bool _Asan_string_should_annotate = true; extern __declspec(selectany) const bool _Asan_vector_should_annotate = true; extern __declspec(selectany) const bool _Asan_optional_should_annotate = true; diff --git a/tests/std/tests/GH_006186_asan_annotate_partial/env.lst b/tests/std/tests/GH_006186_asan_annotate_partial/env.lst index d5adb5844f3..2c694ae2c11 100644 --- a/tests/std/tests/GH_006186_asan_annotate_partial/env.lst +++ b/tests/std/tests/GH_006186_asan_annotate_partial/env.lst @@ -34,7 +34,6 @@ PM_CL="/EHsc /MTd /std:c++latest /permissive" PM_CL="/EHsc /MTd /std:c++latest /permissive- /analyze:only /analyze:autolog-" PM_CL="/EHsc /MTd /std:c++latest /permissive- /fp:strict" PM_CL="/EHsc /MTd /std:c++latest /permissive-" -# TRANSITION, we don't use /ALTERNATENAME for Clang (see GH-5224) so we cannot test /D_ANNOTATE_VECTOR without -fsanitize=address PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MD /std:c++14" PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MD /std:c++17" PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MT /std:c++20 /permissive-" diff --git a/tests/std/tests/GH_006186_asan_annotate_partial/test.cpp b/tests/std/tests/GH_006186_asan_annotate_partial/test.cpp index 55483ef1cc1..17d39988ffc 100644 --- a/tests/std/tests/GH_006186_asan_annotate_partial/test.cpp +++ b/tests/std/tests/GH_006186_asan_annotate_partial/test.cpp @@ -1,5 +1,6 @@ // Copyright (c) Microsoft Corporation. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + // REQUIRES: x64 || x86 || arm64 #if defined(__clang__) && defined(_M_ARM64) // TRANSITION, LLVM-184902, fixed in Clang 23 From 26006f1e6ea2fc7571243ecda2f518867791dee1 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Tue, 14 Apr 2026 05:40:33 -0700 Subject: [PATCH 4/8] Add extern. --- stl/inc/__msvc_sanitizer_annotate_container.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/stl/inc/__msvc_sanitizer_annotate_container.hpp b/stl/inc/__msvc_sanitizer_annotate_container.hpp index 1c3f2e786a8..e9711aab5a3 100644 --- a/stl/inc/__msvc_sanitizer_annotate_container.hpp +++ b/stl/inc/__msvc_sanitizer_annotate_container.hpp @@ -130,15 +130,15 @@ _STL_DISABLE_CLANG_WARNINGS extern "C" { #ifdef _ACTIVATE_STRING_ANNOTATION -__declspec(selectany) const bool _Asan_string_should_annotate = true; +__declspec(selectany) extern const bool _Asan_string_should_annotate = true; #pragma detect_mismatch("annotate_string", "1") #endif // ^^^ defined(_ACTIVATE_STRING_ANNOTATION) ^^^ #ifdef _ACTIVATE_VECTOR_ANNOTATION -__declspec(selectany) const bool _Asan_vector_should_annotate = true; +__declspec(selectany) extern const bool _Asan_vector_should_annotate = true; #pragma detect_mismatch("annotate_vector", "1") #endif // ^^^ defined(_ACTIVATE_VECTOR_ANNOTATION) ^^^ #ifdef _ACTIVATE_OPTIONAL_ANNOTATION -__declspec(selectany) const bool _Asan_optional_should_annotate = true; +__declspec(selectany) extern const bool _Asan_optional_should_annotate = true; #pragma detect_mismatch("annotate_optional", "1") #endif // ^^^ defined(_ACTIVATE_OPTIONAL_ANNOTATION) ^^^ From 88089e5db5fe52e88925437958885c667f1f04d0 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Tue, 14 Apr 2026 05:49:51 -0700 Subject: [PATCH 5/8] Fix grammar: defines => define --- stl/src/asan.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stl/src/asan.cpp b/stl/src/asan.cpp index 4c8e40d70a6..6c5d854282b 100644 --- a/stl/src/asan.cpp +++ b/stl/src/asan.cpp @@ -5,7 +5,7 @@ namespace std { extern "C" { // TRANSITION, ABI: preserved for compatibility with old headers, which // added stl_asan.lib to the link line. We use __declspec(selectany) to be - // compatible with the new headers that defines these variables as + // compatible with the new headers that define these variables as // __declspec(selectany) in __msvc_sanitizer_annotate_container.hpp. // The new method is preferred because previously enabling just string // would also enable vector and optional. See GH-6186 for details. From 65bdbf8fd906fd9b7db20db419eefa321abad588 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Tue, 14 Apr 2026 05:57:45 -0700 Subject: [PATCH 6/8] Style: Move `__declspec(selectany)` to the beginning. --- stl/src/asan.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/stl/src/asan.cpp b/stl/src/asan.cpp index 6c5d854282b..8af75033308 100644 --- a/stl/src/asan.cpp +++ b/stl/src/asan.cpp @@ -9,8 +9,8 @@ namespace std { // __declspec(selectany) in __msvc_sanitizer_annotate_container.hpp. // The new method is preferred because previously enabling just string // would also enable vector and optional. See GH-6186 for details. - extern __declspec(selectany) const bool _Asan_string_should_annotate = true; - extern __declspec(selectany) const bool _Asan_vector_should_annotate = true; - extern __declspec(selectany) const bool _Asan_optional_should_annotate = true; + __declspec(selectany) extern const bool _Asan_string_should_annotate = true; + __declspec(selectany) extern const bool _Asan_vector_should_annotate = true; + __declspec(selectany) extern const bool _Asan_optional_should_annotate = true; } // extern "C" } // namespace std From 3c0c2fdc8f21573ef6f6338b32e439b907f0b5ba Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Tue, 14 Apr 2026 06:01:42 -0700 Subject: [PATCH 7/8] Update test declarations to match headers. --- tests/std/tests/GH_006186_asan_annotate_partial/test.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/std/tests/GH_006186_asan_annotate_partial/test.cpp b/tests/std/tests/GH_006186_asan_annotate_partial/test.cpp index 17d39988ffc..2096f12df85 100644 --- a/tests/std/tests/GH_006186_asan_annotate_partial/test.cpp +++ b/tests/std/tests/GH_006186_asan_annotate_partial/test.cpp @@ -11,9 +11,11 @@ int main() {} #include #include // include __msvc_sanitizer_annotate_container.hpp -extern "C" const bool _Asan_vector_should_annotate; -extern "C" const bool _Asan_string_should_annotate; -extern "C" const bool _Asan_optional_should_annotate; +extern "C" { +extern const bool _Asan_vector_should_annotate; +extern const bool _Asan_string_should_annotate; +extern const bool _Asan_optional_should_annotate; +} // extern "C" int main() { #ifdef TEST_ENSURE_VECTOR_ENABLED From 88995c6c1b0a8e548382f587a512f29644f0bcbc Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Tue, 14 Apr 2026 06:12:55 -0700 Subject: [PATCH 8/8] asan.cpp: Drop `namespace std` outside `extern "C"`. --- stl/src/asan.cpp | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/stl/src/asan.cpp b/stl/src/asan.cpp index 8af75033308..b496e1c6aaa 100644 --- a/stl/src/asan.cpp +++ b/stl/src/asan.cpp @@ -1,16 +1,14 @@ // Copyright (c) Microsoft Corporation. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -namespace std { - extern "C" { - // TRANSITION, ABI: preserved for compatibility with old headers, which - // added stl_asan.lib to the link line. We use __declspec(selectany) to be - // compatible with the new headers that define these variables as - // __declspec(selectany) in __msvc_sanitizer_annotate_container.hpp. - // The new method is preferred because previously enabling just string - // would also enable vector and optional. See GH-6186 for details. - __declspec(selectany) extern const bool _Asan_string_should_annotate = true; - __declspec(selectany) extern const bool _Asan_vector_should_annotate = true; - __declspec(selectany) extern const bool _Asan_optional_should_annotate = true; - } // extern "C" -} // namespace std +extern "C" { +// TRANSITION, ABI: preserved for compatibility with old headers, which +// added stl_asan.lib to the link line. We use __declspec(selectany) to be +// compatible with the new headers that define these variables as +// __declspec(selectany) in __msvc_sanitizer_annotate_container.hpp. +// The new method is preferred because previously enabling just string +// would also enable vector and optional. See GH-6186 for details. +__declspec(selectany) extern const bool _Asan_string_should_annotate = true; +__declspec(selectany) extern const bool _Asan_vector_should_annotate = true; +__declspec(selectany) extern const bool _Asan_optional_should_annotate = true; +} // extern "C"