Skip to content

Conversation

nathanchance
Copy link
Member

@nathanchance nathanchance commented Jul 30, 2025

When the static analyzer is disabled with
-DCLANG_ENABLE_STATIC_ANALYZER=OFF, the newly added
specializations-lazy-load-parentmap-crash.cpp test fails with:

error: action RunAnalysis not compiled in

--



Failed Tests (1):
Clang :: Modules/specializations-lazy-load-parentmap-crash.cpp

Split out the part of the test that requires the static analyzer so that
it does not run when the static analyzer is unavailable.

…-load-parentmap-crash.cpp

When the static analyzer is disabled with
-DCLANG_ENABLE_STATIC_ANALYZER=OFF, the newly added
specializations-lazy-load-parentmap-crash.cpp test fails with:

  error: action RunAnalysis not compiled in

  --

  ********************
  ********************
  Failed Tests (1):
    Clang :: Modules/specializations-lazy-load-parentmap-crash.cpp

Add a 'REQUIRES: staticanalyzer' line to the test so that it does not
run when the static analyzer is unavailable.
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:modules C++20 modules and Clang Header Modules labels Jul 30, 2025
@llvmbot
Copy link
Member

llvmbot commented Jul 30, 2025

@llvm/pr-subscribers-clang-modules

Author: Nathan Chancellor (nathanchance)

Changes

When the static analyzer is disabled with
-DCLANG_ENABLE_STATIC_ANALYZER=OFF, the newly added
specializations-lazy-load-parentmap-crash.cpp test fails with:

error: action RunAnalysis not compiled in

--



Failed Tests (1):
Clang :: Modules/specializations-lazy-load-parentmap-crash.cpp

Add a 'REQUIRES: staticanalyzer' line to the test so that it does not
run when the static analyzer is unavailable.


Full diff: https://github.com/llvm/llvm-project/pull/151259.diff

1 Files Affected:

  • (modified) clang/test/Modules/specializations-lazy-load-parentmap-crash.cpp (+2)
diff --git a/clang/test/Modules/specializations-lazy-load-parentmap-crash.cpp b/clang/test/Modules/specializations-lazy-load-parentmap-crash.cpp
index bd07ada631355..19f9d14102903 100644
--- a/clang/test/Modules/specializations-lazy-load-parentmap-crash.cpp
+++ b/clang/test/Modules/specializations-lazy-load-parentmap-crash.cpp
@@ -1,3 +1,5 @@
+// REQUIRES: staticanalyzer
+//
 // RUN: rm -rf %t
 // RUN: mkdir -p %t
 // RUN: split-file --leading-lines %s %t

@llvmbot
Copy link
Member

llvmbot commented Jul 30, 2025

@llvm/pr-subscribers-clang

Author: Nathan Chancellor (nathanchance)

Changes

When the static analyzer is disabled with
-DCLANG_ENABLE_STATIC_ANALYZER=OFF, the newly added
specializations-lazy-load-parentmap-crash.cpp test fails with:

error: action RunAnalysis not compiled in

--



Failed Tests (1):
Clang :: Modules/specializations-lazy-load-parentmap-crash.cpp

Add a 'REQUIRES: staticanalyzer' line to the test so that it does not
run when the static analyzer is unavailable.


Full diff: https://github.com/llvm/llvm-project/pull/151259.diff

1 Files Affected:

  • (modified) clang/test/Modules/specializations-lazy-load-parentmap-crash.cpp (+2)
diff --git a/clang/test/Modules/specializations-lazy-load-parentmap-crash.cpp b/clang/test/Modules/specializations-lazy-load-parentmap-crash.cpp
index bd07ada631355..19f9d14102903 100644
--- a/clang/test/Modules/specializations-lazy-load-parentmap-crash.cpp
+++ b/clang/test/Modules/specializations-lazy-load-parentmap-crash.cpp
@@ -1,3 +1,5 @@
+// REQUIRES: staticanalyzer
+//
 // RUN: rm -rf %t
 // RUN: mkdir -p %t
 // RUN: split-file --leading-lines %s %t

@nathanchance nathanchance requested a review from ChuanqiXu9 July 30, 2025 00:08
@nathanchance
Copy link
Member Author

cc @michael-jabbour-sonarsource

@michael-jabbour-sonarsource
Copy link
Contributor

Thanks for looking into this! Just to clarify, the test demonstrates two different ways that previously triggered a crash, and only one of them actually requires the static analyzer. I’m not sure if there’s a straightforward way to disable just that specific command when the static analyzer is off, but I wanted to mention it in case it sparks any ideas.

@nathanchance
Copy link
Member Author

Right, I was unsure if there was a way to do that other than splitting the test in some manner. My understanding is that REQUIRES is an all or nothing.

Copy link
Member

@ChuanqiXu9 ChuanqiXu9 left a comment

Choose a reason for hiding this comment

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

LGTM. It will be better if you can split it. It can be achieved by copying the test and remove the corresponding RUN lines. But I don't feel bad if you want to commit it as is since I believe the test may still be covered in a lot of cases.

@nathanchance
Copy link
Member Author

I am happy to split the test if so desired, something like this?

diff --git a/clang/test/Modules/specializations-lazy-load-parentmap-crash-analyzer.cpp b/clang/test/Modules/specializations-lazy-load-parentmap-crash-analyzer.cpp
new file mode 100644
index 000000000000..52b86b1ec27d
--- /dev/null
+++ b/clang/test/Modules/specializations-lazy-load-parentmap-crash-analyzer.cpp
@@ -0,0 +1,98 @@
+// REQUIRES: staticanalyzer
+//
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: split-file --leading-lines %s %t
+//
+// Prepare the BMIs.
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -emit-module-interface -o %t/mod_a-part1.pcm %t/mod_a-part1.cppm
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -emit-module-interface -o %t/mod_a-part2.pcm %t/mod_a-part2.cppm
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -emit-module-interface -o %t/mod_a.pcm %t/mod_a.cppm -fmodule-file=mod_a:part2=%t/mod_a-part2.pcm -fmodule-file=mod_a:part1=%t/mod_a-part1.pcm
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -emit-module-interface -o %t/mod_b.pcm %t/mod_b.cppm -fmodule-file=mod_a:part2=%t/mod_a-part2.pcm -fmodule-file=mod_a=%t/mod_a.pcm -fmodule-file=mod_a:part1=%t/mod_a-part1.pcm
+
+// Trigger the construction of the parent map (which is necessary to trigger the bug this regression test is for) using ArrayBoundV2 checker:
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -analyze -analyzer-checker=security,alpha.security -analyzer-output=text %t/test-array-bound-v2.cpp -fmodule-file=mod_a:part2=%t/mod_a-part2.pcm -fmodule-file=mod_a=%t/mod_a.pcm -fmodule-file=mod_a:part1=%t/mod_a-part1.pcm -fmodule-file=mod_b=%t/mod_b.pcm
+
+//--- mod_a-part1.cppm
+module;
+namespace mod_a {
+template <int> struct Important;
+}
+
+namespace mod_a {
+Important<0>& instantiate1();
+} // namespace mod_a
+export module mod_a:part1;
+
+export namespace mod_a {
+using ::mod_a::instantiate1;
+}
+
+//--- mod_a-part2.cppm
+module;
+namespace mod_a {
+template <int> struct Important;
+}
+
+namespace mod_a {
+template <int N> Important<N>& instantiate2();
+namespace part2InternalInstantiations {
+// During the construction of the parent map, we iterate over ClassTemplateDecl::specializations() for 'Important'.
+// After GH119333, the following instantiations get loaded between the call to spec_begin() and spec_end().
+// This used to invalidate the begin iterator returned by spec_begin() by the time the end iterator is returned.
+// This is a regression test for that.
+Important<1> fn1();
+Important<2> fn2();
+Important<3> fn3();
+Important<4> fn4();
+Important<5> fn5();
+Important<6> fn6();
+Important<7> fn7();
+Important<8> fn8();
+Important<9> fn9();
+Important<10> fn10();
+Important<11> fn11();
+}
+} // namespace mod_a
+export module mod_a:part2;
+
+export namespace mod_a {
+using ::mod_a::instantiate2;
+}
+
+//--- mod_a.cppm
+export module mod_a;
+export import :part1;
+export import :part2;
+
+//--- mod_b.cppm
+export module mod_b;
+import mod_a;
+
+void a() {
+  mod_a::instantiate1();
+  mod_a::instantiate2<42>();
+}
+
+//--- test-array-bound-v2.cpp
+import mod_b;
+
+extern void someFunc(char* first, char* last);
+void triggerParentMapContextCreationThroughArrayBoundV2() {
+  // This code currently causes the ArrayBoundV2 checker to create the ParentMapContext.
+  // Once it detects an access to buf[100], the checker looks through the parents to find '&' operator.
+  // (this is needed since taking the address of past-the-end pointer is allowed by the checker)
+  char buf[100];
+  someFunc(&buf[0], &buf[100]);
+}
+
+//--- test-sanitized-build.cpp
+import mod_b;
+
+extern void some();
+void triggerParentMapContextCreationThroughSanitizedBuild(unsigned i) {
+  // This code currently causes UBSan to create the ParentMapContext.
+  // UBSan currently excludes the pattern below to avoid noise, and it relies on ParentMapContext to detect it.
+  while (i--)
+    some();
+}
diff --git a/clang/test/Modules/specializations-lazy-load-parentmap-crash.cpp b/clang/test/Modules/specializations-lazy-load-parentmap-crash.cpp
index 19f9d1410290..6a70b0722727 100644
--- a/clang/test/Modules/specializations-lazy-load-parentmap-crash.cpp
+++ b/clang/test/Modules/specializations-lazy-load-parentmap-crash.cpp
@@ -10,10 +10,7 @@
 // RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -emit-module-interface -o %t/mod_a.pcm %t/mod_a.cppm -fmodule-file=mod_a:part2=%t/mod_a-part2.pcm -fmodule-file=mod_a:part1=%t/mod_a-part1.pcm
 // RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -emit-module-interface -o %t/mod_b.pcm %t/mod_b.cppm -fmodule-file=mod_a:part2=%t/mod_a-part2.pcm -fmodule-file=mod_a=%t/mod_a.pcm -fmodule-file=mod_a:part1=%t/mod_a-part1.pcm
 
-// Below are two examples to trigger the construction of the parent map (which is necessary to trigger the bug this regression test is for).
-// Using ArrayBoundV2 checker:
-// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -analyze -analyzer-checker=security,alpha.security -analyzer-output=text %t/test-array-bound-v2.cpp -fmodule-file=mod_a:part2=%t/mod_a-part2.pcm -fmodule-file=mod_a=%t/mod_a.pcm -fmodule-file=mod_a:part1=%t/mod_a-part1.pcm -fmodule-file=mod_b=%t/mod_b.pcm
-// Using a sanitized build:
+// Trigger the construction of the parent map (which is necessary to trigger the bug this regression test is for) using ArrayBoundV2 checker using a sanitized build:
 // RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fsanitize=unsigned-integer-overflow -fsanitize-undefined-ignore-overflow-pattern=all -emit-llvm -o %t/ignored %t/test-sanitized-build.cpp -fmodule-file=mod_a:part2=%t/mod_a-part2.pcm -fmodule-file=mod_a=%t/mod_a.pcm -fmodule-file=mod_a:part1=%t/mod_a-part1.pcm -fmodule-file=mod_b=%t/mod_b.pcm
 
 //--- mod_a-part1.cppm

@ChuanqiXu9
Copy link
Member

Yeah

…ns-lazy-load-parentmap-crash.cpp

Signed-off-by: Nathan Chancellor <nathan@kernel.org>
@nathanchance nathanchance changed the title [clang][test] Require staticanalyzer for Modules/specializations-lazy-load-parentmap-crash.cpp [clang][test] Split out staticanalyzer portion of Modules/specializations-lazy-load-parentmap-crash.cpp Aug 1, 2025
@nathanchance
Copy link
Member Author

Thanks, I will merge this when CI allows it.

Copy link
Contributor

@michael-jabbour-sonarsource michael-jabbour-sonarsource left a comment

Choose a reason for hiding this comment

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

LGTM. Thanks for fixing this.

I left a few minor comments. Feel free to ignore if they are not relevant.

// RUN: split-file --leading-lines %s %t
//
// Prepare the BMIs.
// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -emit-module-interface -o %t/mod_a-part1.pcm %t/mod_a-part1.cppm

Choose a reason for hiding this comment

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

Just a small nitpick: I think that the triple argument can be removed from the commands in the ArrayBoundV2 test now that they are separate (they were only needed for the sanitized build test).

Copy link
Member Author

Choose a reason for hiding this comment

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

Sounds good, done in 5e29800.

…ns-lazy-load-parentmap-crash.cpp

Signed-off-by: Nathan Chancellor <nathan@kernel.org>
…ns-lazy-load-parentmap-crash.cpp

Signed-off-by: Nathan Chancellor <nathan@kernel.org>
Copy link
Contributor

Choose a reason for hiding this comment

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

Thank you very much for addressing all the comments @nathanchance. I added one question to make sure I understand the problem correctly.

…ns-lazy-load-parentmap-crash.cpp

Signed-off-by: Nathan Chancellor <nathan@kernel.org>
Copy link
Contributor

Choose a reason for hiding this comment

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

LGTM. Thank you.

@nathanchance nathanchance merged commit a1c3c65 into llvm:main Aug 2, 2025
9 checks passed
@llvm-ci
Copy link
Collaborator

llvm-ci commented Aug 2, 2025

LLVM Buildbot has detected a new failure on builder llvm-clang-x86_64-sie-win running on sie-win-worker while building clang at step 7 "test-build-unified-tree-check-all".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/46/builds/21096

Here is the relevant piece of the build log for the reference
Step 7 (test-build-unified-tree-check-all) failure: test (failure)
******************** TEST 'lld :: COFF/import_weak_alias.test' FAILED ********************
Exit Code: 3221225477

Command Output (stdout):
--
# RUN: at line 3
split-file Z:\b\llvm-clang-x86_64-sie-win\llvm-project\lld\test\COFF\import_weak_alias.test Z:\b\llvm-clang-x86_64-sie-win\build\tools\lld\test\COFF\Output\import_weak_alias.test.tmp.dir
# executed command: split-file 'Z:\b\llvm-clang-x86_64-sie-win\llvm-project\lld\test\COFF\import_weak_alias.test' 'Z:\b\llvm-clang-x86_64-sie-win\build\tools\lld\test\COFF\Output\import_weak_alias.test.tmp.dir'
# note: command had no output on stdout or stderr
# RUN: at line 4
z:\b\llvm-clang-x86_64-sie-win\build\bin\llvm-mc.exe --filetype=obj -triple=x86_64-windows-msvc Z:\b\llvm-clang-x86_64-sie-win\build\tools\lld\test\COFF\Output\import_weak_alias.test.tmp.dir/foo.s -o Z:\b\llvm-clang-x86_64-sie-win\build\tools\lld\test\COFF\Output\import_weak_alias.test.tmp.foo.obj
# executed command: 'z:\b\llvm-clang-x86_64-sie-win\build\bin\llvm-mc.exe' --filetype=obj -triple=x86_64-windows-msvc 'Z:\b\llvm-clang-x86_64-sie-win\build\tools\lld\test\COFF\Output\import_weak_alias.test.tmp.dir/foo.s' -o 'Z:\b\llvm-clang-x86_64-sie-win\build\tools\lld\test\COFF\Output\import_weak_alias.test.tmp.foo.obj'
# note: command had no output on stdout or stderr
# RUN: at line 5
z:\b\llvm-clang-x86_64-sie-win\build\bin\llvm-mc.exe --filetype=obj -triple=x86_64-windows-msvc Z:\b\llvm-clang-x86_64-sie-win\build\tools\lld\test\COFF\Output\import_weak_alias.test.tmp.dir/qux.s -o Z:\b\llvm-clang-x86_64-sie-win\build\tools\lld\test\COFF\Output\import_weak_alias.test.tmp.qux.obj
# executed command: 'z:\b\llvm-clang-x86_64-sie-win\build\bin\llvm-mc.exe' --filetype=obj -triple=x86_64-windows-msvc 'Z:\b\llvm-clang-x86_64-sie-win\build\tools\lld\test\COFF\Output\import_weak_alias.test.tmp.dir/qux.s' -o 'Z:\b\llvm-clang-x86_64-sie-win\build\tools\lld\test\COFF\Output\import_weak_alias.test.tmp.qux.obj'
# note: command had no output on stdout or stderr
# RUN: at line 6
z:\b\llvm-clang-x86_64-sie-win\build\bin\lld-link.exe Z:\b\llvm-clang-x86_64-sie-win\build\tools\lld\test\COFF\Output\import_weak_alias.test.tmp.qux.obj Z:\b\llvm-clang-x86_64-sie-win\build\tools\lld\test\COFF\Output\import_weak_alias.test.tmp.foo.obj -out:Z:\b\llvm-clang-x86_64-sie-win\build\tools\lld\test\COFF\Output\import_weak_alias.test.tmp.dll -dll
# executed command: 'z:\b\llvm-clang-x86_64-sie-win\build\bin\lld-link.exe' 'Z:\b\llvm-clang-x86_64-sie-win\build\tools\lld\test\COFF\Output\import_weak_alias.test.tmp.qux.obj' 'Z:\b\llvm-clang-x86_64-sie-win\build\tools\lld\test\COFF\Output\import_weak_alias.test.tmp.foo.obj' '-out:Z:\b\llvm-clang-x86_64-sie-win\build\tools\lld\test\COFF\Output\import_weak_alias.test.tmp.dll' -dll
# .---command stderr------------
# | PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
# | Stack dump:
# | 0.	Program arguments: z:\\b\\llvm-clang-x86_64-sie-win\\build\\bin\\lld-link.exe Z:\\b\\llvm-clang-x86_64-sie-win\\build\\tools\\lld\\test\\COFF\\Output\\import_weak_alias.test.tmp.qux.obj Z:\\b\\llvm-clang-x86_64-sie-win\\build\\tools\\lld\\test\\COFF\\Output\\import_weak_alias.test.tmp.foo.obj -out:Z:\\b\\llvm-clang-x86_64-sie-win\\build\\tools\\lld\\test\\COFF\\Output\\import_weak_alias.test.tmp.dll -dll
# | Exception Code: 0xC0000005
# | #0 0x00007ff8e5361b39 (C:\Windows\System32\KERNELBASE.dll+0x41b39)
# | #1 0x00007ff6a755bb18 (z:\b\llvm-clang-x86_64-sie-win\build\bin\lld-link.exe+0xcbb18)
# | #2 0x00007ff6a75e32db (z:\b\llvm-clang-x86_64-sie-win\build\bin\lld-link.exe+0x1532db)
# | #3 0x00007ff6a753d9aa (z:\b\llvm-clang-x86_64-sie-win\build\bin\lld-link.exe+0xad9aa)
# | #4 0x00007ff6a753da14 (z:\b\llvm-clang-x86_64-sie-win\build\bin\lld-link.exe+0xada14)
# | #5 0x00007ff6a9cb0614 (z:\b\llvm-clang-x86_64-sie-win\build\bin\lld-link.exe+0x2820614)
# | #6 0x00007ff8e7947ac4 (C:\Windows\System32\KERNEL32.DLL+0x17ac4)
# | #7 0x00007ff8e879a8c1 (C:\Windows\SYSTEM32\ntdll.dll+0x5a8c1)
# `-----------------------------
# error: command failed with exit status: 0xc0000005

--

********************


@nathanchance nathanchance deleted the fix-specializations-lazy-load-parentmap-crash-test-no-static-analyzer branch August 3, 2025 01:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:modules C++20 modules and Clang Header Modules clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants