Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions stl/modules/std.compat.ixx
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
// Copyright (c) Microsoft Corporation.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

module;

#ifdef __clang__
#pragma clang diagnostic push
// warning: 'std' is a reserved name for a module [-Wreserved-module-identifier]
#pragma clang diagnostic ignored "-Wreserved-module-identifier"
#endif // defined(__clang__)

export module std.compat;

export import std;
Expand Down Expand Up @@ -531,3 +539,7 @@ export using std::towlower;
export using std::towupper;
export using std::towctrans;
export using std::wctrans;

#ifdef __clang__
#pragma clang diagnostic pop
#endif // defined(__clang__)
14 changes: 14 additions & 0 deletions stl/modules/std.ixx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,17 @@ module;
// <intrin.h> defines some types outside of `extern "C"` or `extern "C++"`.
#include <intrin.h>

#ifdef __clang__
#include <malloc.h> // TRANSITION, LLVM-37969

#pragma clang diagnostic push
// warning: '#include <filename>' attaches the declarations to the named module 'std', which is not usually intended;
// consider moving that directive before the module declaration [-Winclude-angled-in-module-purview]
// warning: 'std' is a reserved name for a module [-Wreserved-module-identifier]
#pragma clang diagnostic ignored "-Winclude-angled-in-module-purview"
#pragma clang diagnostic ignored "-Wreserved-module-identifier"
#endif // defined(__clang__)

export module std;

#pragma warning(push)
Expand Down Expand Up @@ -155,3 +166,6 @@ export module std;
#include <cwctype>

#pragma warning(pop)
#ifdef __clang__
#pragma clang diagnostic pop
#endif // defined(__clang__)
6 changes: 6 additions & 0 deletions tests/std/include/test_header_units_and_modules.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,7 @@ void test_future() {
assert(f.get() == 1729);
}

#if !(defined(__clang__) && defined(_M_ARM64EC)) // TRANSITION, LLVM-158341
#if TEST_STANDARD >= 23
void test_generator() {
using namespace std;
Expand All @@ -297,6 +298,7 @@ void test_generator() {
assert(ranges::equal(some_ints(bound), views::iota(0, bound)));
}
#endif // TEST_STANDARD >= 23
#endif // ^^^ no workaround ^^^

void test_initializer_list() {
using namespace std;
Expand Down Expand Up @@ -755,7 +757,9 @@ constexpr bool impl_test_source_location() {
using namespace std;
const auto sl = source_location::current();
assert(sl.line() == __LINE__ - 1);
#ifndef __clang__
assert(sl.column() == 38);
#endif // !defined(__clang__)

#ifdef __EDG__
assert(sl.function_name() == "bool impl_test_source_location()"sv);
Expand Down Expand Up @@ -1198,9 +1202,11 @@ void all_cpp_header_tests() {
test_fstream();
test_functional();
test_future();
#if !(defined(__clang__) && defined(_M_ARM64EC)) // TRANSITION, LLVM-158341
#if TEST_STANDARD >= 23
test_generator();
#endif // TEST_STANDARD >= 23
#endif // ^^^ no workaround ^^^
test_initializer_list();
test_iomanip();
test_ios();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,21 @@ def getBuildSteps(self, test, litConfig, shared):
test4Cpp = os.path.join(sourceDir, 'test4.cpp')
classicCpp = os.path.join(sourceDir, 'classic.cpp')

# Dependency order is important here:
inputPaths = [stdIxx, stdCompatIxx, testCpp, test2Cpp, test3Cpp, test4Cpp, classicCpp]
moduleUnits = [stdIxx, stdCompatIxx]
traditionalUnits = [testCpp, test2Cpp, test3Cpp, test4Cpp, classicCpp]

cmd = [test.cxx, *inputPaths, *test.flags, *test.compileFlags]
if 'clang' in test.cxx:
Copy link

Copilot AI Apr 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Clang detection is case-sensitive ('clang' in test.cxx). Elsewhere in the lit harness the compiler is identified case-insensitively (see tests/utils/stl/test/tests.py using casefold()), so this can fail to recognize Clang for differently-cased paths and skip the --precompile steps. Please make the check case-insensitive (preferably using os.path.basename(test.cxx).casefold()) or key off the existing clang feature.

Suggested change
if 'clang' in test.cxx:
if 'clang' in os.path.basename(test.cxx).casefold():

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if 'clang' in test.cxx:
if 'clang' in test.config.available_features:

for modulePath in moduleUnits:
cmd = [test.cxx, '-x', 'c++-module', modulePath, '--precompile', *test.flags, *test.compileFlags]
yield TestStep(cmd, shared.execDir, shared.env, False)

inputPaths = ['-x', 'c++-module', *moduleUnits, '-x', 'none', *traditionalUnits]
cmd = [test.cxx, *inputPaths, *test.flags, *test.compileFlags]
else:
# Dependency order is important here:
inputPaths = [*moduleUnits, *traditionalUnits]

cmd = [test.cxx, *inputPaths, *test.flags, *test.compileFlags]

if TestType.COMPILE in test.testType:
cmd += ['/c']
Expand Down
17 changes: 14 additions & 3 deletions tests/std/tests/P2465R3_standard_library_modules/custombuild.pl
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,20 @@ ()
my $stdIxx = "$stlModulesDir\\std.ixx";
my $stdCompatIxx = "$stlModulesDir\\std.compat.ixx";

# Dependency order is important here:
my @inputPaths = ($stdIxx, $stdCompatIxx, "test.cpp", "test2.cpp", "test3.cpp", "test4.cpp", "classic.cpp");
my @moduleUnits = ($stdIxx, $stdCompatIxx);
my @traditionalUnits = ("test.cpp", "test2.cpp", "test3.cpp", "test4.cpp", "classic.cpp");

Run::ExecuteCL(join(" ", @inputPaths, "/Fe$cwd.exe"));
if ($ENV{PM_COMPILER} =~ m/clang/) {
Copy link

Copilot AI Apr 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This Clang detection is case-sensitive ($ENV{PM_COMPILER} =~ m/clang/). If PM_COMPILER is set to a differently-cased value/path, the Clang module precompile path will be skipped and the build will likely fail. Consider using a case-insensitive regex (/clang/i).

Suggested change
if ($ENV{PM_COMPILER} =~ m/clang/) {
if ($ENV{PM_COMPILER} =~ m/clang/i) {

Copilot uses AI. Check for mistakes.
for my $modulePath (@moduleUnits) {
Run::ExecuteCL("-x c++-module $modulePath --precompile");
}

Run::ExecuteCL(join(" ", "-x", "c++-module", @moduleUnits, "-x", "none", @traditionalUnits, "/Fe$cwd.exe"));
} else {
# Dependency order is important here:
my @inputPaths = ($stdIxx, $stdCompatIxx, "test.cpp", "test2.cpp", "test3.cpp", "test4.cpp", "classic.cpp");

Run::ExecuteCL(join(" ", @inputPaths, "/Fe$cwd.exe"));
}
}
1
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,17 @@ def getBuildSteps(self, test, litConfig, shared):
sourceDir = os.path.dirname(testCpp)
userIxx = os.path.join(sourceDir, 'user.ixx')

# Dependency order is important here:
inputPaths = [userIxx, testCpp]
if 'clang' in test.cxx:
cmd = [test.cxx, '-x', 'c++-module', userIxx, '--precompile', *test.flags, *test.compileFlags]
yield TestStep(cmd, shared.execDir, shared.env, False)
Comment on lines +18 to +20
Copy link

Copilot AI Apr 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Clang detection is case-sensitive ('clang' in test.cxx). tests/utils/stl/test/tests.py treats compiler names case-insensitively (via casefold()), so this can mis-detect Clang if the compiler path contains different casing (e.g. Clang-cl.exe) and then skip the required --precompile steps. Consider switching to a case-insensitive check (e.g. based on os.path.basename(test.cxx).casefold()) or using the existing clang feature instead of substring matching.

See below for a potential fix:

        compiler_name = os.path.basename(test.cxx).casefold()

        if 'clang' in compiler_name:

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah there's an existing feature.

Suggested change
if 'clang' in test.cxx:
cmd = [test.cxx, '-x', 'c++-module', userIxx, '--precompile', *test.flags, *test.compileFlags]
yield TestStep(cmd, shared.execDir, shared.env, False)
if 'clang' in test.config.available_features:
cmd = [test.cxx, '-x', 'c++-module', userIxx, '--precompile', *test.flags, *test.compileFlags]
yield TestStep(cmd, shared.execDir, shared.env, False)


cmd = [test.cxx, *inputPaths, *test.flags, *test.compileFlags]
inputPaths = ['-x', 'c++-module', userIxx, '-x', 'none', testCpp]
cmd = [test.cxx, *inputPaths, *test.flags, *test.compileFlags]
else:
# Dependency order is important here:
inputPaths = [userIxx, testCpp]

cmd = [test.cxx, *inputPaths, *test.flags, *test.compileFlags]

if TestType.COMPILE in test.testType:
cmd += ['/c']
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,14 @@ ()
{
my $cwd = Run::GetCWDName();

# Dependency order is important here:
my @inputPaths = ("user.ixx", "test.cpp");
if ($ENV{PM_COMPILER} =~ m/clang/) {
Copy link

Copilot AI Apr 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This Clang detection is case-sensitive ($ENV{PM_COMPILER} =~ m/clang/). If PM_COMPILER is provided with different casing (e.g. an absolute path with Clang-cl.exe), the Clang-specific module build steps will be skipped. Consider using a case-insensitive regex (/clang/i) to make the detection robust.

Suggested change
if ($ENV{PM_COMPILER} =~ m/clang/) {
if ($ENV{PM_COMPILER} =~ m/clang/i) {

Copilot uses AI. Check for mistakes.
Run::ExecuteCL("-x c++-module user.ixx --precompile");
Run::ExecuteCL("-x c++-module user.ixx -x none test.cpp /Fe$cwd.exe");
} else {
# Dependency order is important here:
my @inputPaths = ("user.ixx", "test.cpp");

Run::ExecuteCL(join(" ", @inputPaths, "/Fe$cwd.exe"));
Run::ExecuteCL(join(" ", @inputPaths, "/Fe$cwd.exe"));
}
}
1
29 changes: 18 additions & 11 deletions tests/std/tests/modules_20_matrix.lst
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,25 @@

RUNALL_INCLUDE ..\..\universal_prefix.lst
RUNALL_CROSSLIST
* PM_CL="/w14365 /D_ENFORCE_FACET_SPECIALIZATIONS=1 /Zc:preprocessor"
* PM_CL="/w14365 /D_ENFORCE_FACET_SPECIALIZATIONS=1"
RUNALL_CROSSLIST
* PM_CL="/w14640 /Zc:threadSafeInit- /EHsc /DTEST_STANDARD=20 /std:c++20"
* PM_CL="/w14640 /Zc:threadSafeInit- /EHsc /DTEST_STANDARD=23 /std:c++latest"
RUNALL_CROSSLIST
* PM_CL="/MD"
* PM_CL="/MDd"
* PM_CL="/MT"
* PM_CL="/MTd"
* PM_CL="/MDd /analyze:only /analyze:autolog-"
* PM_CL="/MDd /GR- /D_HAS_STATIC_RTTI=0"
* PM_CL="/MDd /utf-8"
RUNALL_CROSSLIST
PM_CL=""
ASAN PM_CL="-fsanitize=address /Zi" PM_LINK="/debug"
PM_CL="/MD /Zc:preprocessor"
ASAN PM_CL="/MD /Zc:preprocessor -fsanitize=address /Zi" PM_LINK="/debug"
PM_CL="/MDd /Zc:preprocessor"
ASAN PM_CL="/MDd /Zc:preprocessor -fsanitize=address /Zi" PM_LINK="/debug"
PM_CL="/MT /Zc:preprocessor"
ASAN PM_CL="/MT /Zc:preprocessor -fsanitize=address /Zi" PM_LINK="/debug"
PM_CL="/MTd /Zc:preprocessor"
ASAN PM_CL="/MTd /Zc:preprocessor -fsanitize=address /Zi" PM_LINK="/debug"
PM_CL="/MDd /analyze:only /analyze:autolog- /Zc:preprocessor"
ASAN PM_CL="/MDd /analyze:only /analyze:autolog- /Zc:preprocessor -fsanitize=address /Zi" PM_LINK="/debug"
PM_CL="/MDd /GR- /D_HAS_STATIC_RTTI=0 /Zc:preprocessor"
ASAN PM_CL="/MDd /GR- /D_HAS_STATIC_RTTI=0 /Zc:preprocessor -fsanitize=address /Zi" PM_LINK="/debug"
PM_CL="/MDd /utf-8 /Zc:preprocessor"
ASAN PM_CL="/MDd /utf-8 /Zc:preprocessor -fsanitize=address /Zi" PM_LINK="/debug"
PM_COMPILER="clang-cl" PM_CL="-fprebuilt-module-path=. -Wno-unqualified-std-cast-call /MD"
PM_COMPILER="clang-cl" PM_CL="-fprebuilt-module-path=. -Wno-unqualified-std-cast-call /MTd"
PM_COMPILER="clang-cl" PM_CL="-fprebuilt-module-path=. -Wno-unqualified-std-cast-call /MT"