llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang

@llvm/pr-subscribers-clang-modules

Author: Michael Spencer (Bigcheese)

<details>
<summary>Changes</summary>

There are build systems that put explicitly built modules in the same module 
cache directory as implicitly built modules. Pruning those in an implicit build 
can cause the build to fail due to missing modules.

rdar://174790709

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


4 Files Affected:

- (modified) clang/include/clang/Serialization/ModuleCache.h (+2-1) 
- (modified) clang/lib/Serialization/ModuleCache.cpp (+3-2) 
- (added) clang/test/Modules/prune-no-toplevel.m (+24) 
- (modified) clang/tools/libclang/BuildSystem.cpp (+2-1) 


``````````diff
diff --git a/clang/include/clang/Serialization/ModuleCache.h 
b/clang/include/clang/Serialization/ModuleCache.h
index 82c4cde37c5ff..dcac8ee9890a9 100644
--- a/clang/include/clang/Serialization/ModuleCache.h
+++ b/clang/include/clang/Serialization/ModuleCache.h
@@ -70,7 +70,8 @@ class ModuleCache {
 std::shared_ptr<ModuleCache> createCrossProcessModuleCache();
 
 /// Shared implementation of `ModuleCache::maybePrune()`.
-void maybePruneImpl(StringRef Path, time_t PruneInterval, time_t PruneAfter);
+void maybePruneImpl(StringRef Path, time_t PruneInterval, time_t PruneAfter,
+                    bool PruneTopLevel = false);
 
 /// Shared implementation of `ModuleCache::write()`.
 std::error_code writeImpl(StringRef Path, llvm::MemoryBufferRef Buffer);
diff --git a/clang/lib/Serialization/ModuleCache.cpp 
b/clang/lib/Serialization/ModuleCache.cpp
index 9ea4223a2eb83..d2d3d3fd9ed76 100644
--- a/clang/lib/Serialization/ModuleCache.cpp
+++ b/clang/lib/Serialization/ModuleCache.cpp
@@ -26,7 +26,7 @@ static void writeTimestampFile(StringRef TimestampFile) {
 }
 
 void clang::maybePruneImpl(StringRef Path, time_t PruneInterval,
-                           time_t PruneAfter) {
+                           time_t PruneAfter, bool PruneTopLevel) {
   if (PruneInterval <= 0 || PruneAfter <= 0)
     return;
 
@@ -95,7 +95,8 @@ void clang::maybePruneImpl(StringRef Path, time_t 
PruneInterval,
        Dir != DirEnd && !EC; Dir.increment(EC)) {
     // If we don't have a directory, try to prune it as a file in the root.
     if (!llvm::sys::fs::is_directory(Dir->path())) {
-      TryPruneFile(Dir->path());
+      if (PruneTopLevel)
+        TryPruneFile(Dir->path());
       continue;
     }
 
diff --git a/clang/test/Modules/prune-no-toplevel.m 
b/clang/test/Modules/prune-no-toplevel.m
new file mode 100644
index 0000000000000..93810b66d399c
--- /dev/null
+++ b/clang/test/Modules/prune-no-toplevel.m
@@ -0,0 +1,24 @@
+// NetBSD: noatime mounts currently inhibit 'touch -a' updates
+// UNSUPPORTED: system-netbsd
+
+// Test that implicit module builds don't prune top-level files in the module
+// cache directory.
+
+// Set up a module cache with a timestamp old enough to trigger pruning, a
+// top-level .pcm, and a stale .pcm in a subdirectory.
+// RUN: rm -rf %t
+// RUN: mkdir -p %t/cache/subdir
+// RUN: touch -m -a -t 201101010000 %t/cache/modules.timestamp
+// RUN: touch -a -t 201101010000 %t/cache/toplevel.pcm
+// RUN: touch -a -t 201101010000 %t/cache/subdir/stale.pcm
+
+// Run the compiler to trigger pruning.
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t/cache 
-fmodules-prune-interval=172800 -fmodules-prune-after=345600 %s -verify
+
+// The top-level .pcm file should still exist.
+// RUN: ls %t/cache/toplevel.pcm
+
+// The subdirectory .pcm file should have been pruned.
+// RUN: not ls %t/cache/subdir/stale.pcm
+
+// expected-no-diagnostics
diff --git a/clang/tools/libclang/BuildSystem.cpp 
b/clang/tools/libclang/BuildSystem.cpp
index e81f69d9960f2..c2319e184f5ef 100644
--- a/clang/tools/libclang/BuildSystem.cpp
+++ b/clang/tools/libclang/BuildSystem.cpp
@@ -155,5 +155,6 @@ void 
clang_ModuleMapDescriptor_dispose(CXModuleMapDescriptor MMD) {
 void clang_ModuleCache_prune(const char *Path, time_t PruneInterval,
                              time_t PruneAfter) {
   if (Path)
-    clang::maybePruneImpl(Path, PruneInterval, PruneAfter);
+    clang::maybePruneImpl(Path, PruneInterval, PruneAfter,
+                          /*PruneTopLevel=*/true);
 }

``````````

</details>


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

Reply via email to