https://github.com/vsapsai updated 
https://github.com/llvm/llvm-project/pull/176537

>From ce48e5df96af6db973c1024a29daa526e8f38f35 Mon Sep 17 00:00:00 2001
From: Volodymyr Sapsai <[email protected]>
Date: Fri, 16 Jan 2026 23:09:37 -0800
Subject: [PATCH 1/2] [Modules] Add a test case when we are skipping module
 validation with a build session and use an outdated module.

Check how it works in CI.

rdar://165237499
---
 ...build-session-validation-outdated-module.c | 86 +++++++++++++++++++
 1 file changed, 86 insertions(+)
 create mode 100644 
clang/test/Modules/build-session-validation-outdated-module.c

diff --git a/clang/test/Modules/build-session-validation-outdated-module.c 
b/clang/test/Modules/build-session-validation-outdated-module.c
new file mode 100644
index 0000000000000..693d1a8fd2cd3
--- /dev/null
+++ b/clang/test/Modules/build-session-validation-outdated-module.c
@@ -0,0 +1,86 @@
+// Test build session validation with parallel compilation for incremental 
builds.
+//
+// Shell is required for clang execution in background.
+// REQUIRES: shell
+
+// RUN: rm -rf %t
+// RUN: split-file %s %t
+// Use the same command line arguments to ensure .pcm files are in the same 
location.
+// RUN: echo "-fsyntax-only -I %/t/include"                      > %t/ctx.rsp
+// RUN: echo "-fmodules -fmodules-cache-path=%/t/module-cache"  >> %t/ctx.rsp
+// RUN: echo "-fbuild-session-file=%/t/session.timestamp"       >> %t/ctx.rsp
+// RUN: echo "-fmodules-validate-once-per-build-session"        >> %t/ctx.rsp
+// RUN: echo "-Xclang -fno-modules-force-validate-user-headers" >> %t/ctx.rsp
+//
+// Add a build session file to avoid errors that it's missing. Doesn't do 
anything as we start with a clean build.
+// RUN: touch %t/session.timestamp
+// Generate a header that takes noticeable time to parse.
+// RUN: %python %t/generate-expensive-header.py > %t/include/expensive-header.h
+//
+// Create SignatureExpectation.pcm with a specific Target signature.
+// RUN: cp %t/version1.h %t/include/target.h
+// RUN: echo "#include <signature-expectation.h>" | %clang @%t/ctx.rsp -x c -
+//
+// Built a different Target.pcm with a different signature.
+// RUN: cp %t/version2.h %t/include/target.h
+// Update the build session to rebuild Target.
+// RUN: touch %t/session.timestamp
+// RUN: echo "#include <target.h>" | %clang @%t/ctx.rsp -x c -
+//
+// Simulate the incremental build.
+// RUN: cp %t/version3.h %t/include/target.h
+// RUN: touch %t/session.timestamp
+// RUN: sleep 1s
+// Compile 2 files in parallel.
+// RUN: %clang @%t/ctx.rsp %t/use-outdated-module.c &
+// RUN: %clang @%t/ctx.rsp %t/rebuild-outdated-module.c
+// RUN: wait
+
+//--- include/module.modulemap
+module Target {
+  header "target.h"
+  textual header "expensive-header.h"
+  export *
+}
+
+module SignatureExpectation {
+  header "signature-expectation.h"
+  export *
+}
+
+//--- version1.h
+// empty
+
+//--- version2.h
+void some_func(void);
+
+//--- version3.h
+#define TARGET_MACRO 1
+
+//--- generate-expensive-header.py
+num_items = 500000
+for i in range(num_items):
+    print(f"struct struct_{i} {{ int x; float *y; }};")
+    print(f"void func_{i}(int *x);")
+    
+//--- include/signature-expectation.h
+// Expensive header is used to slow down the build of SignatureExpectation 
module.
+// Without the slow down we are able to validate and rebuild Target before 
another process can do it.
+#include <expensive-header.h>
+#include <target.h>
+
+//--- use-outdated-module.c
+// At first load SignatureExpectation module, so it would load Target but
+// reject it due to a signature mismatch.
+// After this we rebuild SignatureExpectation and try to use already loaded
+// Target buffer when encounter corresponding include in the source code.
+#include <signature-expectation.h>
+
+#ifndef TARGET_MACRO
+# error Macro is missing, probably using outdated Target module
+#endif
+
+//--- rebuild-outdated-module.c
+// We aim for another process to load the outdated module Target with
+// the wrong signature before we rebuild it.
+#include <target.h>

>From 5344902cafffb92973d7a3a69f156200dcc225e0 Mon Sep 17 00:00:00 2001
From: Volodymyr Sapsai <[email protected]>
Date: Mon, 19 Jan 2026 22:04:05 -0800
Subject: [PATCH 2/2] Move the test to clang-scan-deps as it will scan on
 multiple threads.

---
 ...build-session-validation-outdated-module.c | 122 ++++++++++++++++++
 ...build-session-validation-outdated-module.c |  86 ------------
 2 files changed, 122 insertions(+), 86 deletions(-)
 create mode 100644 
clang/test/ClangScanDeps/build-session-validation-outdated-module.c
 delete mode 100644 
clang/test/Modules/build-session-validation-outdated-module.c

diff --git 
a/clang/test/ClangScanDeps/build-session-validation-outdated-module.c 
b/clang/test/ClangScanDeps/build-session-validation-outdated-module.c
new file mode 100644
index 0000000000000..7f2296aa4ae14
--- /dev/null
+++ b/clang/test/ClangScanDeps/build-session-validation-outdated-module.c
@@ -0,0 +1,122 @@
+// Test build session validation with parallel compilation for incremental 
builds.
+
+// RUN: rm -rf %t
+// RUN: split-file %s %t
+// Use the same command line arguments to ensure .pcm files are in the same 
location.
+// RUN: echo "-fsyntax-only -I %/t/include"                      > %t/ctx.rsp
+// RUN: echo "-fmodules -fmodules-cache-path=%/t/module-cache"  >> %t/ctx.rsp
+// RUN: echo "-fbuild-session-file=%/t/session.timestamp"       >> %t/ctx.rsp
+// RUN: echo "-fmodules-validate-once-per-build-session"        >> %t/ctx.rsp
+//
+// Add a build session file to avoid errors that it's missing. Doesn't do 
anything as we start with a clean build.
+// RUN: touch %t/session.timestamp
+// Generate headers that take noticeable time to parse. The purpose is to 
tweak the timing, so can reproduce the error.
+// RUN: %python %t/generate-expensive-header.py A 2000000 > 
%t/include/expensive-header.h
+// RUN: %python %t/generate-expensive-header.py B 500000 > 
%t/include/less-expensive-header.h
+//
+// Create SignatureExpectation.pcm with a specific Target signature.
+// RUN: cp %t/version1.h %t/include/target.h
+// RUN: sed "s|DIR|%/t|g" %t/prepare-expected-signature.json.template > 
%t/prepare-expected-signature.json
+// RUN: clang-scan-deps -compilation-database 
%t/prepare-expected-signature.json > /dev/null
+//
+// Built a different Target.pcm with a different signature.
+// RUN: cp %t/version2.h %t/include/target.h
+// Update the build session to rebuild Target.
+// RUN: touch %t/session.timestamp
+// RUN: sed "s|DIR|%/t|g" %t/create-outdated-module.json.template > 
%t/create-outdated-module.json
+// RUN: clang-scan-deps -compilation-database %t/create-outdated-module.json > 
/dev/null
+//
+// Simulate the incremental build.
+// RUN: cp %t/version3.h %t/include/target.h
+// RUN: touch %t/session.timestamp
+// Scan 2 files in parallel.
+// RUN: sed "s|DIR|%/t|g" %t/incremental.json.template > %t/incremental.json
+// RUN: clang-scan-deps -compilation-database %t/incremental.json > /dev/null
+
+//--- include/module.modulemap
+module Target {
+  header "target.h"
+  export *
+}
+
+module SignatureExpectation {
+  header "signature-expectation.h"
+  textual header "expensive-header.h"
+  export *
+}
+
+//--- version1.h
+// empty
+
+//--- version2.h
+void some_func(void);
+
+//--- version3.h
+void some_func(void);
+#define TARGET_MACRO 1
+
+//--- generate-expensive-header.py
+import sys
+
+num_items = int(sys.argv[2])
+suffix = sys.argv[1]
+for i in range(num_items):
+    if i == 0:
+        print(f"#define MACRO_{suffix}_{i} 0")
+    else:
+        print(f"#define MACRO_{suffix}_{i} MACRO_{suffix}_{i-1} + 1")
+    
+//--- include/signature-expectation.h
+// Expensive header is used to slow down the build of SignatureExpectation 
module.
+// Without the slow down we are able to validate and rebuild Target before 
another thread can do it.
+#include <expensive-header.h>
+#include <target.h>
+
+//--- prepare-expected-signature.c
+#include <signature-expectation.h>
+//--- prepare-expected-signature.json.template
+[{                                                                             
 
+  "file": "DIR/prepare-expected-signature.c",
+  "directory": "DIR",
+  "command": "clang @DIR/ctx.rsp DIR/prepare-expected-signature.c"
+}] 
+
+//--- create-outdated-module.c
+#include <target.h>
+//--- create-outdated-module.json.template
+[{                                                                             
 
+  "file": "DIR/create-outdated-module.c",
+  "directory": "DIR",
+  "command": "clang @DIR/ctx.rsp DIR/create-outdated-module.c"
+}] 
+
+//--- use-outdated-module.c
+// At first load SignatureExpectation module, so it would load Target but
+// reject it due to a signature mismatch.
+// After this we rebuild SignatureExpectation and try to use already loaded
+// Target buffer when encounter corresponding include in the source code.
+// The problem is that it corresponds to version2.h and not version3.h.
+#include <signature-expectation.h>
+
+#ifndef TARGET_MACRO
+# error Macro is missing, probably using outdated Target module
+# include <missing macro>
+#endif
+
+//--- rebuild-outdated-module.c
+// We aim for another thread to load the outdated module Target with
+// the wrong signature before we rebuild it.
+#include <less-expensive-header.h>
+#include <target.h>
+
+//--- incremental.json.template
+[{                                                                             
 
+  "file": "DIR/use-outdated-module.c",
+  "directory": "DIR",
+  "command": "clang @DIR/ctx.rsp DIR/use-outdated-module.c"
+},
+{                                                                              
+  "file": "DIR/rebuild-outdated-module.c",
+  "directory": "DIR",
+  "command": "clang @DIR/ctx.rsp DIR/rebuild-outdated-module.c"
+}] 
diff --git a/clang/test/Modules/build-session-validation-outdated-module.c 
b/clang/test/Modules/build-session-validation-outdated-module.c
deleted file mode 100644
index 693d1a8fd2cd3..0000000000000
--- a/clang/test/Modules/build-session-validation-outdated-module.c
+++ /dev/null
@@ -1,86 +0,0 @@
-// Test build session validation with parallel compilation for incremental 
builds.
-//
-// Shell is required for clang execution in background.
-// REQUIRES: shell
-
-// RUN: rm -rf %t
-// RUN: split-file %s %t
-// Use the same command line arguments to ensure .pcm files are in the same 
location.
-// RUN: echo "-fsyntax-only -I %/t/include"                      > %t/ctx.rsp
-// RUN: echo "-fmodules -fmodules-cache-path=%/t/module-cache"  >> %t/ctx.rsp
-// RUN: echo "-fbuild-session-file=%/t/session.timestamp"       >> %t/ctx.rsp
-// RUN: echo "-fmodules-validate-once-per-build-session"        >> %t/ctx.rsp
-// RUN: echo "-Xclang -fno-modules-force-validate-user-headers" >> %t/ctx.rsp
-//
-// Add a build session file to avoid errors that it's missing. Doesn't do 
anything as we start with a clean build.
-// RUN: touch %t/session.timestamp
-// Generate a header that takes noticeable time to parse.
-// RUN: %python %t/generate-expensive-header.py > %t/include/expensive-header.h
-//
-// Create SignatureExpectation.pcm with a specific Target signature.
-// RUN: cp %t/version1.h %t/include/target.h
-// RUN: echo "#include <signature-expectation.h>" | %clang @%t/ctx.rsp -x c -
-//
-// Built a different Target.pcm with a different signature.
-// RUN: cp %t/version2.h %t/include/target.h
-// Update the build session to rebuild Target.
-// RUN: touch %t/session.timestamp
-// RUN: echo "#include <target.h>" | %clang @%t/ctx.rsp -x c -
-//
-// Simulate the incremental build.
-// RUN: cp %t/version3.h %t/include/target.h
-// RUN: touch %t/session.timestamp
-// RUN: sleep 1s
-// Compile 2 files in parallel.
-// RUN: %clang @%t/ctx.rsp %t/use-outdated-module.c &
-// RUN: %clang @%t/ctx.rsp %t/rebuild-outdated-module.c
-// RUN: wait
-
-//--- include/module.modulemap
-module Target {
-  header "target.h"
-  textual header "expensive-header.h"
-  export *
-}
-
-module SignatureExpectation {
-  header "signature-expectation.h"
-  export *
-}
-
-//--- version1.h
-// empty
-
-//--- version2.h
-void some_func(void);
-
-//--- version3.h
-#define TARGET_MACRO 1
-
-//--- generate-expensive-header.py
-num_items = 500000
-for i in range(num_items):
-    print(f"struct struct_{i} {{ int x; float *y; }};")
-    print(f"void func_{i}(int *x);")
-    
-//--- include/signature-expectation.h
-// Expensive header is used to slow down the build of SignatureExpectation 
module.
-// Without the slow down we are able to validate and rebuild Target before 
another process can do it.
-#include <expensive-header.h>
-#include <target.h>
-
-//--- use-outdated-module.c
-// At first load SignatureExpectation module, so it would load Target but
-// reject it due to a signature mismatch.
-// After this we rebuild SignatureExpectation and try to use already loaded
-// Target buffer when encounter corresponding include in the source code.
-#include <signature-expectation.h>
-
-#ifndef TARGET_MACRO
-# error Macro is missing, probably using outdated Target module
-#endif
-
-//--- rebuild-outdated-module.c
-// We aim for another process to load the outdated module Target with
-// the wrong signature before we rebuild it.
-#include <target.h>

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to