[llvm] [llvm-ar] fix inconsistent case sensitivity for path matching on Windows (PR #196541)

via llvm-commits llvm-commits at lists.llvm.org
Thu May 28 00:29:23 PDT 2026


https://github.com/0xFE4415 updated https://github.com/llvm/llvm-project/pull/196541

>From ef5eb93be6c57324a338e445ec61bd4c165409ea Mon Sep 17 00:00:00 2001
From: Luna <259395 at student.pwr.edu.pl>
Date: Sat, 2 May 2026 22:43:39 +0200
Subject: [PATCH 01/22] extended test

---
 .../test/tools/llvm-ar/windows-name-case.test | 31 +++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/llvm/test/tools/llvm-ar/windows-name-case.test b/llvm/test/tools/llvm-ar/windows-name-case.test
index 970a3e616d3c7..4b93e203ca21c 100644
--- a/llvm/test/tools/llvm-ar/windows-name-case.test
+++ b/llvm/test/tools/llvm-ar/windows-name-case.test
@@ -27,3 +27,34 @@
 # RUN: FileCheck %s -input-file=%t/thin-archive.a --check-prefix=EMPTY --implicit-check-not {{.}}
 
 EMPTY: !<thin>
+
+# File instance counting should respect Windows case-insensitive name matching.
+# Otherwise, if you have foo.txt and FOO.TXT, "-N 2 foo.txt" fails with because
+# file is not found.
+
+# RUN: mkdir -p %t/a %t/b
+# RUN: echo first > %t/a/foo.txt
+# RUN: echo second > %t/b/FOO.TXT
+# RUN: llvm-ar rc %t/count-case.a %t/a/foo.txt %t/b/FOO.TXT
+
+# RUN: mkdir -p %t/out1 %t/out2
+# RUN: llvm-ar xN 1 --output %t/out1 %t/count-case.a foo.txt
+# RUN: cat %t/out1/foo.txt | FileCheck %s --check-prefix=EXTRACT-FIRST
+# RUN: llvm-ar xN 2 --output %t/out2 %t/count-case.a foo.txt
+# RUN: cat %t/out2/FOO.TXT | FileCheck %s --check-prefix=EXTRACT-SECOND
+# RUN: not llvm-ar xN 3 --output %t/out2 %t/count-case.a foo.txt 2>&1 | FileCheck %s --check-prefix=EXTRACT-NOT-FOUND
+
+# EXTRACT-FIRST: first
+# EXTRACT-SECOND: second
+# EXTRACT-NOT-FOUND: error: 'foo.txt' was not found
+
+# RUN: rm -f %t/delete-count.a
+# RUN: llvm-ar rc %t/delete-count.a %t/a/foo.txt %t/b/FOO.TXT
+# RUN: llvm-ar dN 2 %t/delete-count.a foo.txt
+# RUN: llvm-ar t %t/delete-count.a | FileCheck %s --check-prefix=DELETE-SECOND
+# RUN: llvm-ar dN 1 %t/delete-count.a FOO.TXT
+# RUN: llvm-ar t %t/delete-count.a | FileCheck %s --check-prefix=DELETE-EMPTY --allow-empty
+
+# DELETE-SECOND: foo.txt
+# DELETE-SECOND-NOT: FOO.TXT
+# DELETE-EMPTY-NOT: foo.txt

>From 8b9e7cdb3ba2dcc1c064033391066f1c1f09464e Mon Sep 17 00:00:00 2001
From: Luna <259395 at student.pwr.edu.pl>
Date: Sat, 2 May 2026 22:43:39 +0200
Subject: [PATCH 02/22] Fix llvm-ar CountParam matching for normalized paths.

---
 llvm/tools/llvm-ar/llvm-ar.cpp | 23 ++++++++++++++++-------
 1 file changed, 16 insertions(+), 7 deletions(-)

diff --git a/llvm/tools/llvm-ar/llvm-ar.cpp b/llvm/tools/llvm-ar/llvm-ar.cpp
index 320a903b59e87..7f4ff0c599208 100644
--- a/llvm/tools/llvm-ar/llvm-ar.cpp
+++ b/llvm/tools/llvm-ar/llvm-ar.cpp
@@ -713,8 +713,11 @@ static void performReadOperation(ArchiveOperation Operation,
         });
         if (I == Members.end())
           continue;
-        if (CountParam && ++MemberCount[Name] != CountParam)
-          continue;
+        if (CountParam) {
+          std::string CountKey = normalizePath(*I);
+          if (++MemberCount[CountKey] != CountParam)
+            continue;
+        }
         Members.erase(I);
       }
 
@@ -854,14 +857,20 @@ static InsertAction computeInsertAction(ArchiveOperation Operation,
   if (Operation == QuickAppend || Members.empty())
     return IA_AddOldMember;
 
-  auto MI = find_if(Members, [Name](StringRef Path) {
+  std::string CountKey;
+  auto MI = find_if(Members, [Name, &CountKey](StringRef Path) {
+    SmallString<128> MatchPath(Path);
     if (Thin && !sys::path::is_absolute(Path)) {
       Expected<std::string> PathOrErr =
           computeArchiveRelativePath(ArchiveName, Path);
-      return comparePaths(Name, PathOrErr ? *PathOrErr : Path);
-    } else {
-      return comparePaths(Name, Path);
+      if (PathOrErr) {
+        MatchPath = *PathOrErr;
+      }
     }
+    if (!comparePaths(Name, MatchPath))
+      return false;
+    CountKey = normalizePath(MatchPath);
+    return true;
   });
 
   if (MI == Members.end())
@@ -870,7 +879,7 @@ static InsertAction computeInsertAction(ArchiveOperation Operation,
   Pos = MI;
 
   if (Operation == Delete) {
-    if (CountParam && ++MemberCount[Name] != CountParam)
+    if (CountParam && ++MemberCount[CountKey] != CountParam)
       return IA_AddOldMember;
     return IA_Delete;
   }

>From 164f55fe13a51e5942737fc7da343c901e1f2408 Mon Sep 17 00:00:00 2001
From: Meow <259395 at student.pwr.edu.pl>
Date: Fri, 8 May 2026 16:05:31 +0200
Subject: [PATCH 03/22] fix typo

---
 llvm/test/tools/llvm-ar/windows-name-case.test | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/test/tools/llvm-ar/windows-name-case.test b/llvm/test/tools/llvm-ar/windows-name-case.test
index 4b93e203ca21c..e94583dc12eb1 100644
--- a/llvm/test/tools/llvm-ar/windows-name-case.test
+++ b/llvm/test/tools/llvm-ar/windows-name-case.test
@@ -29,7 +29,7 @@
 EMPTY: !<thin>
 
 # File instance counting should respect Windows case-insensitive name matching.
-# Otherwise, if you have foo.txt and FOO.TXT, "-N 2 foo.txt" fails with because
+# Otherwise, if you have foo.txt and FOO.TXT, "-N 2 foo.txt" fails because
 # file is not found.
 
 # RUN: mkdir -p %t/a %t/b

>From 7a38e057a486b686e960020c38f8e8d3d3e07b15 Mon Sep 17 00:00:00 2001
From: Meow <259395 at student.pwr.edu.pl>
Date: Tue, 12 May 2026 16:41:37 +0200
Subject: [PATCH 04/22] Apply suggestion from @0xFE4415

---
 llvm/test/tools/llvm-ar/windows-name-case.test | 1 +
 1 file changed, 1 insertion(+)

diff --git a/llvm/test/tools/llvm-ar/windows-name-case.test b/llvm/test/tools/llvm-ar/windows-name-case.test
index e94583dc12eb1..169b6bf086d74 100644
--- a/llvm/test/tools/llvm-ar/windows-name-case.test
+++ b/llvm/test/tools/llvm-ar/windows-name-case.test
@@ -32,6 +32,7 @@ EMPTY: !<thin>
 # Otherwise, if you have foo.txt and FOO.TXT, "-N 2 foo.txt" fails because
 # file is not found.
 
+# RUN: rm -f %t/count-case.a 
 # RUN: mkdir -p %t/a %t/b
 # RUN: echo first > %t/a/foo.txt
 # RUN: echo second > %t/b/FOO.TXT

>From f53f87066f58ab802472e957d0dfb88d915d0bdc Mon Sep 17 00:00:00 2001
From: Meow <259395 at student.pwr.edu.pl>
Date: Wed, 13 May 2026 14:20:30 +0100
Subject: [PATCH 05/22] use count 0

---
 llvm/test/tools/llvm-ar/windows-name-case.test | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/llvm/test/tools/llvm-ar/windows-name-case.test b/llvm/test/tools/llvm-ar/windows-name-case.test
index 169b6bf086d74..ff6759ae61ce9 100644
--- a/llvm/test/tools/llvm-ar/windows-name-case.test
+++ b/llvm/test/tools/llvm-ar/windows-name-case.test
@@ -54,8 +54,7 @@ EMPTY: !<thin>
 # RUN: llvm-ar dN 2 %t/delete-count.a foo.txt
 # RUN: llvm-ar t %t/delete-count.a | FileCheck %s --check-prefix=DELETE-SECOND
 # RUN: llvm-ar dN 1 %t/delete-count.a FOO.TXT
-# RUN: llvm-ar t %t/delete-count.a | FileCheck %s --check-prefix=DELETE-EMPTY --allow-empty
+# RUN: llvm-ar t %t/delete-count.a | count 0
 
 # DELETE-SECOND: foo.txt
 # DELETE-SECOND-NOT: FOO.TXT
-# DELETE-EMPTY-NOT: foo.txt

>From 0df65185a7144f37170f2234be186c1c059189bf Mon Sep 17 00:00:00 2001
From: Meow <259395 at student.pwr.edu.pl>
Date: Wed, 13 May 2026 14:20:51 +0100
Subject: [PATCH 06/22] use ## for comments

---
 llvm/test/tools/llvm-ar/windows-name-case.test | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/llvm/test/tools/llvm-ar/windows-name-case.test b/llvm/test/tools/llvm-ar/windows-name-case.test
index ff6759ae61ce9..ee2f4dcdb7b4b 100644
--- a/llvm/test/tools/llvm-ar/windows-name-case.test
+++ b/llvm/test/tools/llvm-ar/windows-name-case.test
@@ -28,9 +28,9 @@
 
 EMPTY: !<thin>
 
-# File instance counting should respect Windows case-insensitive name matching.
-# Otherwise, if you have foo.txt and FOO.TXT, "-N 2 foo.txt" fails because
-# file is not found.
+## File instance counting should respect Windows case-insensitive name matching.
+## Otherwise, if you have foo.txt and FOO.TXT, "-N 2 foo.txt" fails because
+## file is not found.
 
 # RUN: rm -f %t/count-case.a 
 # RUN: mkdir -p %t/a %t/b

>From 6dd79db3c1b0b7da4b14c866549fd5a70759a2fc Mon Sep 17 00:00:00 2001
From: Meow <259395 at student.pwr.edu.pl>
Date: Wed, 13 May 2026 14:38:37 +0100
Subject: [PATCH 07/22] use implicit check not

---
 llvm/test/tools/llvm-ar/windows-name-case.test | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/llvm/test/tools/llvm-ar/windows-name-case.test b/llvm/test/tools/llvm-ar/windows-name-case.test
index ee2f4dcdb7b4b..7ade7b1ae7e65 100644
--- a/llvm/test/tools/llvm-ar/windows-name-case.test
+++ b/llvm/test/tools/llvm-ar/windows-name-case.test
@@ -52,9 +52,8 @@ EMPTY: !<thin>
 # RUN: rm -f %t/delete-count.a
 # RUN: llvm-ar rc %t/delete-count.a %t/a/foo.txt %t/b/FOO.TXT
 # RUN: llvm-ar dN 2 %t/delete-count.a foo.txt
-# RUN: llvm-ar t %t/delete-count.a | FileCheck %s --check-prefix=DELETE-SECOND
+# RUN: llvm-ar t %t/delete-count.a | FileCheck %s --check-prefix=DELETE-SECOND --implicit-check-not={{.*}}
 # RUN: llvm-ar dN 1 %t/delete-count.a FOO.TXT
 # RUN: llvm-ar t %t/delete-count.a | count 0
 
 # DELETE-SECOND: foo.txt
-# DELETE-SECOND-NOT: FOO.TXT

>From 87022dee47506f0cd27155d364b14e37813d7b05 Mon Sep 17 00:00:00 2001
From: Meow <259395 at student.pwr.edu.pl>
Date: Wed, 13 May 2026 16:06:48 +0100
Subject: [PATCH 08/22] fix test

---
 llvm/test/tools/llvm-ar/windows-name-case.test | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/test/tools/llvm-ar/windows-name-case.test b/llvm/test/tools/llvm-ar/windows-name-case.test
index 7ade7b1ae7e65..0fd73758e9520 100644
--- a/llvm/test/tools/llvm-ar/windows-name-case.test
+++ b/llvm/test/tools/llvm-ar/windows-name-case.test
@@ -52,8 +52,8 @@ EMPTY: !<thin>
 # RUN: rm -f %t/delete-count.a
 # RUN: llvm-ar rc %t/delete-count.a %t/a/foo.txt %t/b/FOO.TXT
 # RUN: llvm-ar dN 2 %t/delete-count.a foo.txt
-# RUN: llvm-ar t %t/delete-count.a | FileCheck %s --check-prefix=DELETE-SECOND --implicit-check-not={{.*}}
+# RUN: llvm-ar t %t/delete-count.a | FileCheck %s --check-prefix=DELETE-SECOND --implicit-check-not={{FOO\.TXT}}
 # RUN: llvm-ar dN 1 %t/delete-count.a FOO.TXT
 # RUN: llvm-ar t %t/delete-count.a | count 0
 
-# DELETE-SECOND: foo.txt
+# DELETE-SECOND: foo.txt
\ No newline at end of file

>From 450ad7b1a874f4d30cd64422f94e38ae06916ac0 Mon Sep 17 00:00:00 2001
From: Meow <259395 at student.pwr.edu.pl>
Date: Wed, 13 May 2026 22:30:56 +0100
Subject: [PATCH 09/22] omit brances around if body

---
 llvm/tools/llvm-ar/llvm-ar.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/llvm/tools/llvm-ar/llvm-ar.cpp b/llvm/tools/llvm-ar/llvm-ar.cpp
index 7f4ff0c599208..bac99c548a178 100644
--- a/llvm/tools/llvm-ar/llvm-ar.cpp
+++ b/llvm/tools/llvm-ar/llvm-ar.cpp
@@ -863,9 +863,8 @@ static InsertAction computeInsertAction(ArchiveOperation Operation,
     if (Thin && !sys::path::is_absolute(Path)) {
       Expected<std::string> PathOrErr =
           computeArchiveRelativePath(ArchiveName, Path);
-      if (PathOrErr) {
+      if (PathOrErr)
         MatchPath = *PathOrErr;
-      }
     }
     if (!comparePaths(Name, MatchPath))
       return false;

>From 0fd92abb865e2107ce37addeda9e8d95db6cf267 Mon Sep 17 00:00:00 2001
From: Meow <259395 at student.pwr.edu.pl>
Date: Thu, 14 May 2026 17:22:08 +0100
Subject: [PATCH 10/22] use . in regex pattern

---
 llvm/test/tools/llvm-ar/windows-name-case.test | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/test/tools/llvm-ar/windows-name-case.test b/llvm/test/tools/llvm-ar/windows-name-case.test
index 0fd73758e9520..d2de0b4465275 100644
--- a/llvm/test/tools/llvm-ar/windows-name-case.test
+++ b/llvm/test/tools/llvm-ar/windows-name-case.test
@@ -52,7 +52,7 @@ EMPTY: !<thin>
 # RUN: rm -f %t/delete-count.a
 # RUN: llvm-ar rc %t/delete-count.a %t/a/foo.txt %t/b/FOO.TXT
 # RUN: llvm-ar dN 2 %t/delete-count.a foo.txt
-# RUN: llvm-ar t %t/delete-count.a | FileCheck %s --check-prefix=DELETE-SECOND --implicit-check-not={{FOO\.TXT}}
+# RUN: llvm-ar t %t/delete-count.a | FileCheck %s --check-prefix=DELETE-SECOND --implicit-check-not={{.}}
 # RUN: llvm-ar dN 1 %t/delete-count.a FOO.TXT
 # RUN: llvm-ar t %t/delete-count.a | count 0
 

>From cc24190774ea5eaee66e9e579f49fe44d6a69779 Mon Sep 17 00:00:00 2001
From: 0xfe4415 <259395 at student.pwr.edu.pl>
Date: Mon, 18 May 2026 17:26:12 +0200
Subject: [PATCH 11/22] update release notes

---
 llvm/docs/ReleaseNotes.md | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index 98f2205bc06a7..6e21bc114afe8 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -244,6 +244,8 @@ Makes programs 10x faster by doing Special New Thing.
   prefixes, making it an alias of the existing `-check-prefixes` option.
 * Add `-mtune` option to `llc`.
 * Add `-mtune` option to `opt`.
+* Fixed `llvm-ar` now correctly handles the `N` count modifier on Windows for archive members whose names differ only
+  in case (e.g. `FOO.OBJ` and `foo.obj`). Previously, `-N 2` would fail with "not found" even when two matching members existed.
 
 ### Changes to LLDB
 

>From 2b59a3dd15a77d6b0e866cca3c1d91669c7609c9 Mon Sep 17 00:00:00 2001
From: Meow <259395 at student.pwr.edu.pl>
Date: Tue, 19 May 2026 15:06:00 +0200
Subject: [PATCH 12/22] release-note: grammar fix

---
 llvm/docs/ReleaseNotes.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index 6e21bc114afe8..8c755801e922c 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -244,7 +244,7 @@ Makes programs 10x faster by doing Special New Thing.
   prefixes, making it an alias of the existing `-check-prefixes` option.
 * Add `-mtune` option to `llc`.
 * Add `-mtune` option to `opt`.
-* Fixed `llvm-ar` now correctly handles the `N` count modifier on Windows for archive members whose names differ only
+* Fixed `llvm-ar` to correctly handle the `N` count modifier on Windows for archive members whose names differ only
   in case (e.g. `FOO.OBJ` and `foo.obj`). Previously, `-N 2` would fail with "not found" even when two matching members existed.
 
 ### Changes to LLDB

>From 775f1bd8b4dafe1acd5e65756f7f229ccd199ebf Mon Sep 17 00:00:00 2001
From: Meow <259395 at student.pwr.edu.pl>
Date: Wed, 20 May 2026 19:45:08 +0100
Subject: [PATCH 13/22] add thin archive test

---
 .../test/tools/llvm-ar/windows-name-case.test | 24 ++++++++++++++++++-
 1 file changed, 23 insertions(+), 1 deletion(-)

diff --git a/llvm/test/tools/llvm-ar/windows-name-case.test b/llvm/test/tools/llvm-ar/windows-name-case.test
index d2de0b4465275..c7d3757ca639f 100644
--- a/llvm/test/tools/llvm-ar/windows-name-case.test
+++ b/llvm/test/tools/llvm-ar/windows-name-case.test
@@ -56,4 +56,26 @@ EMPTY: !<thin>
 # RUN: llvm-ar dN 1 %t/delete-count.a FOO.TXT
 # RUN: llvm-ar t %t/delete-count.a | count 0
 
-# DELETE-SECOND: foo.txt
\ No newline at end of file
+# DELETE-SECOND: foo.txt
+
+## test thin archive d option with -P and N modifiers (full path matching)
+
+# RUN: echo one > %t/a/file.txt
+
+# RUN: rm -f %t/archive-dPN.a
+# RUN: llvm-ar rc --thin %t/archive-dPN.a %t/a/file.txt %t/a/FILE.txt
+# RUN: llvm-ar t %t/archive-dPN.a | FileCheck %s --check-prefix=THIN-BEFORE -DPATH=%/t --implicit-check-not={{.}}
+
+## third does not exists, expect no-op
+# RUN: llvm-ar dPN 3 --thin %t/archive-dPN.a %t/a/file.txt
+# RUN: llvm-ar t %t/archive-dPN.a | FileCheck %s --check-prefix=THIN-BEFORE -DPATH=%/t --implicit-check-not={{.}}
+
+# RUN: llvm-ar dPN 2 --thin %t/archive-dPN.a %t/a/file.txt
+# RUN: llvm-ar t %t/archive-dPN.a | FileCheck %s --check-prefix=THIN-AFTER -DPATH=%/t --implicit-check-not={{.}}
+# RUN: llvm-ar dPN 1 --thin %t/archive-dPN.a %t/a/file.txt
+# RUN: llvm-ar t %t/archive-dPN.a | count 0
+
+# THIN-BEFORE: [[PATH]]/a/file.txt
+# THIN-BEFORE: [[PATH]]/a/FILE.txt
+
+# THIN-AFTER: [[PATH]]/a/file.txt

>From 89d6ff9024712a96ae66abad0aed13a60e8f6625 Mon Sep 17 00:00:00 2001
From: Meow <259395 at student.pwr.edu.pl>
Date: Wed, 20 May 2026 19:51:41 +0100
Subject: [PATCH 14/22] del superflous newline

---
 llvm/test/tools/llvm-ar/windows-name-case.test | 1 -
 1 file changed, 1 deletion(-)

diff --git a/llvm/test/tools/llvm-ar/windows-name-case.test b/llvm/test/tools/llvm-ar/windows-name-case.test
index c7d3757ca639f..dc55787435d7b 100644
--- a/llvm/test/tools/llvm-ar/windows-name-case.test
+++ b/llvm/test/tools/llvm-ar/windows-name-case.test
@@ -61,7 +61,6 @@ EMPTY: !<thin>
 ## test thin archive d option with -P and N modifiers (full path matching)
 
 # RUN: echo one > %t/a/file.txt
-
 # RUN: rm -f %t/archive-dPN.a
 # RUN: llvm-ar rc --thin %t/archive-dPN.a %t/a/file.txt %t/a/FILE.txt
 # RUN: llvm-ar t %t/archive-dPN.a | FileCheck %s --check-prefix=THIN-BEFORE -DPATH=%/t --implicit-check-not={{.}}

>From f6bb9731e983c3cf00c0803d61e84e62882b0885 Mon Sep 17 00:00:00 2001
From: Meow <259395 at student.pwr.edu.pl>
Date: Thu, 21 May 2026 11:57:34 +0200
Subject: [PATCH 15/22] apply suggestions

---
 llvm/test/tools/llvm-ar/windows-name-case.test | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/test/tools/llvm-ar/windows-name-case.test b/llvm/test/tools/llvm-ar/windows-name-case.test
index dc55787435d7b..6448343f6bcc5 100644
--- a/llvm/test/tools/llvm-ar/windows-name-case.test
+++ b/llvm/test/tools/llvm-ar/windows-name-case.test
@@ -58,14 +58,14 @@ EMPTY: !<thin>
 
 # DELETE-SECOND: foo.txt
 
-## test thin archive d option with -P and N modifiers (full path matching)
+## Test thin archive d option with P and N modifiers (full path matching).
 
 # RUN: echo one > %t/a/file.txt
 # RUN: rm -f %t/archive-dPN.a
 # RUN: llvm-ar rc --thin %t/archive-dPN.a %t/a/file.txt %t/a/FILE.txt
 # RUN: llvm-ar t %t/archive-dPN.a | FileCheck %s --check-prefix=THIN-BEFORE -DPATH=%/t --implicit-check-not={{.}}
 
-## third does not exists, expect no-op
+## Third does not exist, expect no-op.
 # RUN: llvm-ar dPN 3 --thin %t/archive-dPN.a %t/a/file.txt
 # RUN: llvm-ar t %t/archive-dPN.a | FileCheck %s --check-prefix=THIN-BEFORE -DPATH=%/t --implicit-check-not={{.}}
 

>From ca66adb49b3289c815365ac3db300b5d16fe1555 Mon Sep 17 00:00:00 2001
From: Meow <259395 at student.pwr.edu.pl>
Date: Thu, 21 May 2026 22:32:36 +0100
Subject: [PATCH 16/22] reorganize tests

---
 .../count-case-sensitivity-windows.test       | 52 +++++++++++++++++++
 .../test/tools/llvm-ar/windows-name-case.test | 51 ------------------
 2 files changed, 52 insertions(+), 51 deletions(-)
 create mode 100644 llvm/test/tools/llvm-ar/count-case-sensitivity-windows.test

diff --git a/llvm/test/tools/llvm-ar/count-case-sensitivity-windows.test b/llvm/test/tools/llvm-ar/count-case-sensitivity-windows.test
new file mode 100644
index 0000000000000..cf3b653b173fa
--- /dev/null
+++ b/llvm/test/tools/llvm-ar/count-case-sensitivity-windows.test
@@ -0,0 +1,52 @@
+# REQUIRES: system-windows
+
+## File instance counting should respect Windows case-insensitive name matching.
+## On Windows systems, `foo.txt` and `FOO.TXT` are considered equal (case-insensitive),
+## so `-N 2 foo.txt` should extract `FOO.TXT`.
+
+# RUN: rm -f %t/count-case.a 
+# RUN: mkdir -p %t/a %t/b
+# RUN: echo first > %t/a/foo.txt
+# RUN: echo second > %t/b/FOO.TXT
+# RUN: llvm-ar rc %t/count-case.a %t/a/foo.txt %t/b/FOO.TXT
+
+# RUN: mkdir -p %t/out1 %t/out2
+# RUN: llvm-ar xN 1 --output %t/out1 %t/count-case.a foo.txt
+# RUN: cat %t/out1/foo.txt | FileCheck %s --check-prefix=EXTRACT-FIRST
+# RUN: llvm-ar xN 2 --output %t/out2 %t/count-case.a foo.txt
+# RUN: cat %t/out2/FOO.TXT | FileCheck %s --check-prefix=EXTRACT-SECOND
+# RUN: not llvm-ar xN 3 --output %t/out2 %t/count-case.a foo.txt 2>&1 | FileCheck %s --check-prefix=EXTRACT-NOT-FOUND
+
+# EXTRACT-FIRST: first
+# EXTRACT-SECOND: second
+# EXTRACT-NOT-FOUND: error: 'foo.txt' was not found
+
+# RUN: rm -f %t/delete-count.a
+# RUN: llvm-ar rc %t/delete-count.a %t/a/foo.txt %t/b/FOO.TXT
+# RUN: llvm-ar dN 2 %t/delete-count.a foo.txt
+# RUN: llvm-ar t %t/delete-count.a | FileCheck %s --check-prefix=DELETE-SECOND --implicit-check-not={{.}}
+# RUN: llvm-ar dN 1 %t/delete-count.a FOO.TXT
+# RUN: llvm-ar t %t/delete-count.a | count 0
+
+# DELETE-SECOND: foo.txt
+
+## Test thin archive d option with P and N modifiers (full path matching).
+
+# RUN: echo one > %t/a/file.txt
+# RUN: rm -f %t/archive-dPN.a
+# RUN: llvm-ar rc --thin %t/archive-dPN.a %t/a/file.txt %t/a/FILE.txt
+# RUN: llvm-ar t %t/archive-dPN.a | FileCheck %s --check-prefix=THIN-BEFORE -DPATH=%/t --implicit-check-not={{.}}
+
+## Third does not exist; expect no-op.
+# RUN: llvm-ar dPN 3 --thin %t/archive-dPN.a %t/a/file.txt
+# RUN: llvm-ar t %t/archive-dPN.a | FileCheck %s --check-prefix=THIN-BEFORE -DPATH=%/t --implicit-check-not={{.}}
+
+# RUN: llvm-ar dPN 2 --thin %t/archive-dPN.a %t/a/file.txt
+# RUN: llvm-ar t %t/archive-dPN.a | FileCheck %s --check-prefix=THIN-AFTER -DPATH=%/t --implicit-check-not={{.}}
+# RUN: llvm-ar dPN 1 --thin %t/archive-dPN.a %t/a/file.txt
+# RUN: llvm-ar t %t/archive-dPN.a | count 0
+
+# THIN-BEFORE: [[PATH]]/a/file.txt
+# THIN-BEFORE: [[PATH]]/a/FILE.txt
+
+# THIN-AFTER: [[PATH]]/a/file.txt
diff --git a/llvm/test/tools/llvm-ar/windows-name-case.test b/llvm/test/tools/llvm-ar/windows-name-case.test
index 6448343f6bcc5..970a3e616d3c7 100644
--- a/llvm/test/tools/llvm-ar/windows-name-case.test
+++ b/llvm/test/tools/llvm-ar/windows-name-case.test
@@ -27,54 +27,3 @@
 # RUN: FileCheck %s -input-file=%t/thin-archive.a --check-prefix=EMPTY --implicit-check-not {{.}}
 
 EMPTY: !<thin>
-
-## File instance counting should respect Windows case-insensitive name matching.
-## Otherwise, if you have foo.txt and FOO.TXT, "-N 2 foo.txt" fails because
-## file is not found.
-
-# RUN: rm -f %t/count-case.a 
-# RUN: mkdir -p %t/a %t/b
-# RUN: echo first > %t/a/foo.txt
-# RUN: echo second > %t/b/FOO.TXT
-# RUN: llvm-ar rc %t/count-case.a %t/a/foo.txt %t/b/FOO.TXT
-
-# RUN: mkdir -p %t/out1 %t/out2
-# RUN: llvm-ar xN 1 --output %t/out1 %t/count-case.a foo.txt
-# RUN: cat %t/out1/foo.txt | FileCheck %s --check-prefix=EXTRACT-FIRST
-# RUN: llvm-ar xN 2 --output %t/out2 %t/count-case.a foo.txt
-# RUN: cat %t/out2/FOO.TXT | FileCheck %s --check-prefix=EXTRACT-SECOND
-# RUN: not llvm-ar xN 3 --output %t/out2 %t/count-case.a foo.txt 2>&1 | FileCheck %s --check-prefix=EXTRACT-NOT-FOUND
-
-# EXTRACT-FIRST: first
-# EXTRACT-SECOND: second
-# EXTRACT-NOT-FOUND: error: 'foo.txt' was not found
-
-# RUN: rm -f %t/delete-count.a
-# RUN: llvm-ar rc %t/delete-count.a %t/a/foo.txt %t/b/FOO.TXT
-# RUN: llvm-ar dN 2 %t/delete-count.a foo.txt
-# RUN: llvm-ar t %t/delete-count.a | FileCheck %s --check-prefix=DELETE-SECOND --implicit-check-not={{.}}
-# RUN: llvm-ar dN 1 %t/delete-count.a FOO.TXT
-# RUN: llvm-ar t %t/delete-count.a | count 0
-
-# DELETE-SECOND: foo.txt
-
-## Test thin archive d option with P and N modifiers (full path matching).
-
-# RUN: echo one > %t/a/file.txt
-# RUN: rm -f %t/archive-dPN.a
-# RUN: llvm-ar rc --thin %t/archive-dPN.a %t/a/file.txt %t/a/FILE.txt
-# RUN: llvm-ar t %t/archive-dPN.a | FileCheck %s --check-prefix=THIN-BEFORE -DPATH=%/t --implicit-check-not={{.}}
-
-## Third does not exist, expect no-op.
-# RUN: llvm-ar dPN 3 --thin %t/archive-dPN.a %t/a/file.txt
-# RUN: llvm-ar t %t/archive-dPN.a | FileCheck %s --check-prefix=THIN-BEFORE -DPATH=%/t --implicit-check-not={{.}}
-
-# RUN: llvm-ar dPN 2 --thin %t/archive-dPN.a %t/a/file.txt
-# RUN: llvm-ar t %t/archive-dPN.a | FileCheck %s --check-prefix=THIN-AFTER -DPATH=%/t --implicit-check-not={{.}}
-# RUN: llvm-ar dPN 1 --thin %t/archive-dPN.a %t/a/file.txt
-# RUN: llvm-ar t %t/archive-dPN.a | count 0
-
-# THIN-BEFORE: [[PATH]]/a/file.txt
-# THIN-BEFORE: [[PATH]]/a/FILE.txt
-
-# THIN-AFTER: [[PATH]]/a/file.txt

>From 9cf772e68a0756b3789ce4e0f5a38f641afcecd5 Mon Sep 17 00:00:00 2001
From: Meow <259395 at student.pwr.edu.pl>
Date: Thu, 21 May 2026 22:32:50 +0100
Subject: [PATCH 17/22] add non-windows test

---
 .../tools/llvm-ar/count-case-sensitivity.test | 58 +++++++++++++++++++
 1 file changed, 58 insertions(+)
 create mode 100644 llvm/test/tools/llvm-ar/count-case-sensitivity.test

diff --git a/llvm/test/tools/llvm-ar/count-case-sensitivity.test b/llvm/test/tools/llvm-ar/count-case-sensitivity.test
new file mode 100644
index 0000000000000..883cf03c24d68
--- /dev/null
+++ b/llvm/test/tools/llvm-ar/count-case-sensitivity.test
@@ -0,0 +1,58 @@
+# UNSUPPORTED: system-windows
+
+## File instance counting should be case-sensitive on non-Windows platforms.
+## On non-Windows systems, `foo.txt` and `FOO.TXT` are distinct, so `-N 2 foo.txt`
+## should fail because only one file named `foo.txt` exists.
+
+# RUN: rm -f %t/count-case.a 
+# RUN: mkdir -p %t/a %t/b
+# RUN: echo first > %t/a/foo.txt
+# RUN: echo second > %t/b/FOO.TXT
+# RUN: llvm-ar rc %t/count-case.a %t/a/foo.txt %t/b/FOO.TXT
+
+# RUN: mkdir -p %t/out1 %t/out2
+# RUN: llvm-ar xN 1 --output %t/out1 %t/count-case.a foo.txt
+# RUN: cat %t/out1/foo.txt | FileCheck %s --check-prefix=EXTRACT-FIRST
+# RUN: not llvm-ar xN 2 --output %t/out2 %t/count-case.a foo.txt 2>&1 | FileCheck %s --check-prefix=EXTRACT-NOT-FOUND
+
+# EXTRACT-FIRST: first
+# EXTRACT-NOT-FOUND: error: 'foo.txt' was not found
+
+# RUN: rm -f %t/delete-count.a
+# RUN: llvm-ar rc %t/delete-count.a %t/a/foo.txt %t/b/FOO.TXT
+# RUN: llvm-ar dN 2 %t/delete-count.a FOO.TXT
+# RUN: llvm-ar t %t/delete-count.a | FileCheck %s --check-prefix=ARCHIVE-BEFORE --implicit-check-not={{.}}
+
+# RUN: llvm-ar dN 1 %t/delete-count.a FOO.TXT
+# RUN: llvm-ar t %t/delete-count.a | FileCheck %s --check-prefix=ARCHIVE-AFTER --implicit-check-not={{.}}
+
+# ARCHIVE-BEFORE: foo.txt
+# ARCHIVE-BEFORE: FOO.TXT
+
+# ARCHIVE-AFTER: foo.txt
+
+## Test thin archive d option with P and N modifiers (full path matching).
+
+# RUN: echo one > %t/a/file.txt
+# RUN: echo two > %t/a/FILE.txt
+# RUN: rm -f %t/archive-dPN.a
+# RUN: llvm-ar rc --thin %t/archive-dPN.a %t/a/file.txt %t/a/FILE.txt
+# RUN: llvm-ar t %t/archive-dPN.a | FileCheck %s --check-prefix=THIN-BEFORE -DPATH=%/t --implicit-check-not={{.}}
+
+## Third does not exist; expect no-op.
+# RUN: llvm-ar dPN 3 --thin %t/archive-dPN.a %t/a/file.txt
+# RUN: llvm-ar t %t/archive-dPN.a | FileCheck %s --check-prefix=THIN-BEFORE -DPATH=%/t --implicit-check-not={{.}}
+
+## The uppercase filename occurs only once; expect no-op.
+# RUN: llvm-ar dPN 2 --thin %t/archive-dPN.a %t/a/FILE.txt
+# RUN: llvm-ar t %t/archive-dPN.a | FileCheck %s --check-prefix=THIN-BEFORE -DPATH=%/t --implicit-check-not={{.}}
+
+# RUN: llvm-ar dPN 1 --thin %t/archive-dPN.a %t/a/FILE.txt
+# RUN: llvm-ar t %t/archive-dPN.a | FileCheck %s --check-prefix=THIN-AFTER -DPATH=%/t --implicit-check-not={{.}}
+# RUN: llvm-ar dPN 1 --thin %t/archive-dPN.a %t/a/file.txt
+# RUN: llvm-ar t %t/archive-dPN.a | count 0
+
+# THIN-BEFORE: [[PATH]]/a/file.txt
+# THIN-BEFORE: [[PATH]]/a/FILE.txt
+
+# THIN-AFTER: [[PATH]]/a/file.txt

>From ddcd150faf1ca658c79b2d1b25a2932864df31d0 Mon Sep 17 00:00:00 2001
From: Meow <259395 at student.pwr.edu.pl>
Date: Thu, 21 May 2026 22:50:56 +0100
Subject: [PATCH 18/22] remove redundant test

---
 llvm/test/tools/llvm-ar/count-case-sensitivity.test | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/llvm/test/tools/llvm-ar/count-case-sensitivity.test b/llvm/test/tools/llvm-ar/count-case-sensitivity.test
index 883cf03c24d68..2384cb0282277 100644
--- a/llvm/test/tools/llvm-ar/count-case-sensitivity.test
+++ b/llvm/test/tools/llvm-ar/count-case-sensitivity.test
@@ -39,10 +39,6 @@
 # RUN: llvm-ar rc --thin %t/archive-dPN.a %t/a/file.txt %t/a/FILE.txt
 # RUN: llvm-ar t %t/archive-dPN.a | FileCheck %s --check-prefix=THIN-BEFORE -DPATH=%/t --implicit-check-not={{.}}
 
-## Third does not exist; expect no-op.
-# RUN: llvm-ar dPN 3 --thin %t/archive-dPN.a %t/a/file.txt
-# RUN: llvm-ar t %t/archive-dPN.a | FileCheck %s --check-prefix=THIN-BEFORE -DPATH=%/t --implicit-check-not={{.}}
-
 ## The uppercase filename occurs only once; expect no-op.
 # RUN: llvm-ar dPN 2 --thin %t/archive-dPN.a %t/a/FILE.txt
 # RUN: llvm-ar t %t/archive-dPN.a | FileCheck %s --check-prefix=THIN-BEFORE -DPATH=%/t --implicit-check-not={{.}}

>From 4a9dd5daf1bd87a3e53b21b689adf177eb944a3d Mon Sep 17 00:00:00 2001
From: Luna <259395 at student.pwr.edu.pl>
Date: Sat, 2 May 2026 22:43:39 +0200
Subject: [PATCH 19/22] extended test

---
 .../test/tools/llvm-ar/windows-name-case.test | 39 +++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/llvm/test/tools/llvm-ar/windows-name-case.test b/llvm/test/tools/llvm-ar/windows-name-case.test
index 970a3e616d3c7..9e7bbf0e7fe38 100644
--- a/llvm/test/tools/llvm-ar/windows-name-case.test
+++ b/llvm/test/tools/llvm-ar/windows-name-case.test
@@ -27,3 +27,42 @@
 # RUN: FileCheck %s -input-file=%t/thin-archive.a --check-prefix=EMPTY --implicit-check-not {{.}}
 
 EMPTY: !<thin>
+
+# Verify that -N instance counting respects Windows case-insensitive name
+# matching: an archive containing foo.txt and FOO.TXT must treat both as the
+# same name for counting purposes. Without this, the two spellings are counted
+# separately, so -N 2 fails with "not found" because neither per-spelling
+# counter reaches 2.
+
+# RUN: mkdir -p %t/a %t/b
+# RUN: echo first > %t/a/foo.txt
+# RUN: echo second > %t/b/FOO.TXT
+# RUN: llvm-ar rc %t/count-case.a %t/a/foo.txt %t/b/FOO.TXT
+
+# RUN: mkdir -p %t/out1 %t/out2
+# RUN: llvm-ar xN 1 --output %t/out1 %t/count-case.a foo.txt
+# RUN: cat %t/out1/foo.txt | FileCheck %s --check-prefix=EXTRACT-FIRST
+# RUN: llvm-ar xN 2 --output %t/out2 %t/count-case.a foo.txt
+# RUN: cat %t/out2/FOO.TXT | FileCheck %s --check-prefix=EXTRACT-SECOND
+# RUN: not llvm-ar xN 3 --output %t/out2 %t/count-case.a foo.txt 2>&1 | FileCheck %s --check-prefix=EXTRACT-NOT-FOUND
+
+# EXTRACT-FIRST: first
+# EXTRACT-SECOND: second
+# EXTRACT-NOT-FOUND: error: 'foo.txt' was not found
+
+
+# Verify that -N instance counting respects Windows case-insensitive name
+# matching for delete: an archive containing foo.txt and FOO.TXT must treat
+# both as the same name so -N 2 deletes the second instance and that -N 1
+# deletes the first.
+
+# RUN: rm -f %t/delete-count.a
+# RUN: llvm-ar rc %t/delete-count.a %t/a/foo.txt %t/b/FOO.TXT
+# RUN: llvm-ar dN 2 %t/delete-count.a foo.txt
+# RUN: llvm-ar t %t/delete-count.a | FileCheck %s --check-prefix=DELETE-SECOND
+# RUN: llvm-ar dN 1 %t/delete-count.a FOO.TXT
+# RUN: llvm-ar t %t/delete-count.a | FileCheck %s --check-prefix=DELETE-EMPTY --allow-empty
+
+# DELETE-SECOND: foo.txt
+# DELETE-SECOND-NOT: FOO.TXT
+# DELETE-EMPTY-NOT: foo.txt

>From fa39c198e69756a65818d43f5c0ebee8ed4f2e06 Mon Sep 17 00:00:00 2001
From: 0xFE4415 <259395 at student.pwr.edu.pl>
Date: Thu, 28 May 2026 08:49:23 +0200
Subject: [PATCH 20/22] use temp dir for test files

---
 .../count-case-sensitivity-windows.test       | 60 +++++++++----------
 .../tools/llvm-ar/count-case-sensitivity.test | 56 +++++++++--------
 2 files changed, 56 insertions(+), 60 deletions(-)

diff --git a/llvm/test/tools/llvm-ar/count-case-sensitivity-windows.test b/llvm/test/tools/llvm-ar/count-case-sensitivity-windows.test
index cf3b653b173fa..f7bd8c48589f6 100644
--- a/llvm/test/tools/llvm-ar/count-case-sensitivity-windows.test
+++ b/llvm/test/tools/llvm-ar/count-case-sensitivity-windows.test
@@ -4,49 +4,47 @@
 ## On Windows systems, `foo.txt` and `FOO.TXT` are considered equal (case-insensitive),
 ## so `-N 2 foo.txt` should extract `FOO.TXT`.
 
-# RUN: rm -f %t/count-case.a 
-# RUN: mkdir -p %t/a %t/b
-# RUN: echo first > %t/a/foo.txt
-# RUN: echo second > %t/b/FOO.TXT
-# RUN: llvm-ar rc %t/count-case.a %t/a/foo.txt %t/b/FOO.TXT
-
-# RUN: mkdir -p %t/out1 %t/out2
-# RUN: llvm-ar xN 1 --output %t/out1 %t/count-case.a foo.txt
-# RUN: cat %t/out1/foo.txt | FileCheck %s --check-prefix=EXTRACT-FIRST
-# RUN: llvm-ar xN 2 --output %t/out2 %t/count-case.a foo.txt
-# RUN: cat %t/out2/FOO.TXT | FileCheck %s --check-prefix=EXTRACT-SECOND
-# RUN: not llvm-ar xN 3 --output %t/out2 %t/count-case.a foo.txt 2>&1 | FileCheck %s --check-prefix=EXTRACT-NOT-FOUND
+# RUN: rm -rf %t && mkdir %t && cd %t
+# RUN: mkdir a b
+# RUN: echo first > a/foo.txt
+# RUN: echo second > b/FOO.TXT
+# RUN: llvm-ar rc count-case.a a/foo.txt b/FOO.TXT
+
+# RUN: mkdir out1 out2
+# RUN: llvm-ar xN 1 --output out1 count-case.a foo.txt
+# RUN: cat out1/foo.txt | FileCheck %s --check-prefix=EXTRACT-FIRST
+# RUN: llvm-ar xN 2 --output out2 count-case.a foo.txt
+# RUN: cat out2/FOO.TXT | FileCheck %s --check-prefix=EXTRACT-SECOND
+# RUN: not llvm-ar xN 3 --output out2 count-case.a foo.txt 2>&1 | FileCheck %s --check-prefix=EXTRACT-NOT-FOUND
 
 # EXTRACT-FIRST: first
 # EXTRACT-SECOND: second
 # EXTRACT-NOT-FOUND: error: 'foo.txt' was not found
 
-# RUN: rm -f %t/delete-count.a
-# RUN: llvm-ar rc %t/delete-count.a %t/a/foo.txt %t/b/FOO.TXT
-# RUN: llvm-ar dN 2 %t/delete-count.a foo.txt
-# RUN: llvm-ar t %t/delete-count.a | FileCheck %s --check-prefix=DELETE-SECOND --implicit-check-not={{.}}
-# RUN: llvm-ar dN 1 %t/delete-count.a FOO.TXT
-# RUN: llvm-ar t %t/delete-count.a | count 0
+# RUN: llvm-ar rc delete-count.a a/foo.txt b/FOO.TXT
+# RUN: llvm-ar dN 2 delete-count.a foo.txt
+# RUN: llvm-ar t delete-count.a | FileCheck %s --check-prefix=DELETE-SECOND --implicit-check-not={{.}}
+# RUN: llvm-ar dN 1 delete-count.a FOO.TXT
+# RUN: llvm-ar t delete-count.a | count 0
 
 # DELETE-SECOND: foo.txt
 
 ## Test thin archive d option with P and N modifiers (full path matching).
 
-# RUN: echo one > %t/a/file.txt
-# RUN: rm -f %t/archive-dPN.a
-# RUN: llvm-ar rc --thin %t/archive-dPN.a %t/a/file.txt %t/a/FILE.txt
-# RUN: llvm-ar t %t/archive-dPN.a | FileCheck %s --check-prefix=THIN-BEFORE -DPATH=%/t --implicit-check-not={{.}}
+# RUN: echo one > a/file.txt
+# RUN: llvm-ar rc --thin archive-dPN.a a/file.txt a/FILE.txt
+# RUN: llvm-ar t archive-dPN.a | FileCheck %s --check-prefix=THIN-BEFORE --implicit-check-not={{.}}
 
 ## Third does not exist; expect no-op.
-# RUN: llvm-ar dPN 3 --thin %t/archive-dPN.a %t/a/file.txt
-# RUN: llvm-ar t %t/archive-dPN.a | FileCheck %s --check-prefix=THIN-BEFORE -DPATH=%/t --implicit-check-not={{.}}
+# RUN: llvm-ar dPN 3 --thin archive-dPN.a a/file.txt
+# RUN: llvm-ar t archive-dPN.a | FileCheck %s --check-prefix=THIN-BEFORE --implicit-check-not={{.}}
 
-# RUN: llvm-ar dPN 2 --thin %t/archive-dPN.a %t/a/file.txt
-# RUN: llvm-ar t %t/archive-dPN.a | FileCheck %s --check-prefix=THIN-AFTER -DPATH=%/t --implicit-check-not={{.}}
-# RUN: llvm-ar dPN 1 --thin %t/archive-dPN.a %t/a/file.txt
-# RUN: llvm-ar t %t/archive-dPN.a | count 0
+# RUN: llvm-ar dPN 2 --thin archive-dPN.a a/file.txt
+# RUN: llvm-ar t archive-dPN.a | FileCheck %s --check-prefix=THIN-AFTER --implicit-check-not={{.}}
+# RUN: llvm-ar dPN 1 --thin archive-dPN.a a/file.txt
+# RUN: llvm-ar t archive-dPN.a | count 0
 
-# THIN-BEFORE: [[PATH]]/a/file.txt
-# THIN-BEFORE: [[PATH]]/a/FILE.txt
+# THIN-BEFORE: a/file.txt
+# THIN-BEFORE: a/FILE.txt
 
-# THIN-AFTER: [[PATH]]/a/file.txt
+# THIN-AFTER: a/file.txt
diff --git a/llvm/test/tools/llvm-ar/count-case-sensitivity.test b/llvm/test/tools/llvm-ar/count-case-sensitivity.test
index 2384cb0282277..f12a9b329d877 100644
--- a/llvm/test/tools/llvm-ar/count-case-sensitivity.test
+++ b/llvm/test/tools/llvm-ar/count-case-sensitivity.test
@@ -4,27 +4,26 @@
 ## On non-Windows systems, `foo.txt` and `FOO.TXT` are distinct, so `-N 2 foo.txt`
 ## should fail because only one file named `foo.txt` exists.
 
-# RUN: rm -f %t/count-case.a 
-# RUN: mkdir -p %t/a %t/b
-# RUN: echo first > %t/a/foo.txt
-# RUN: echo second > %t/b/FOO.TXT
-# RUN: llvm-ar rc %t/count-case.a %t/a/foo.txt %t/b/FOO.TXT
+# RUN: rm -rf %t && mkdir %t && cd %t
+# RUN: mkdir a b
+# RUN: echo first > a/foo.txt
+# RUN: echo second > b/FOO.TXT
+# RUN: llvm-ar rc count-case.a a/foo.txt b/FOO.TXT
 
-# RUN: mkdir -p %t/out1 %t/out2
-# RUN: llvm-ar xN 1 --output %t/out1 %t/count-case.a foo.txt
-# RUN: cat %t/out1/foo.txt | FileCheck %s --check-prefix=EXTRACT-FIRST
-# RUN: not llvm-ar xN 2 --output %t/out2 %t/count-case.a foo.txt 2>&1 | FileCheck %s --check-prefix=EXTRACT-NOT-FOUND
+# RUN: mkdir out1 out2
+# RUN: llvm-ar xN 1 --output out1 count-case.a foo.txt
+# RUN: cat out1/foo.txt | FileCheck %s --check-prefix=EXTRACT-FIRST
+# RUN: not llvm-ar xN 2 --output out2 count-case.a foo.txt 2>&1 | FileCheck %s --check-prefix=EXTRACT-NOT-FOUND
 
 # EXTRACT-FIRST: first
 # EXTRACT-NOT-FOUND: error: 'foo.txt' was not found
 
-# RUN: rm -f %t/delete-count.a
-# RUN: llvm-ar rc %t/delete-count.a %t/a/foo.txt %t/b/FOO.TXT
-# RUN: llvm-ar dN 2 %t/delete-count.a FOO.TXT
-# RUN: llvm-ar t %t/delete-count.a | FileCheck %s --check-prefix=ARCHIVE-BEFORE --implicit-check-not={{.}}
+# RUN: llvm-ar rc delete-count.a a/foo.txt b/FOO.TXT
+# RUN: llvm-ar dN 2 delete-count.a FOO.TXT
+# RUN: llvm-ar t delete-count.a | FileCheck %s --check-prefix=ARCHIVE-BEFORE --implicit-check-not={{.}}
 
-# RUN: llvm-ar dN 1 %t/delete-count.a FOO.TXT
-# RUN: llvm-ar t %t/delete-count.a | FileCheck %s --check-prefix=ARCHIVE-AFTER --implicit-check-not={{.}}
+# RUN: llvm-ar dN 1 delete-count.a FOO.TXT
+# RUN: llvm-ar t delete-count.a | FileCheck %s --check-prefix=ARCHIVE-AFTER --implicit-check-not={{.}}
 
 # ARCHIVE-BEFORE: foo.txt
 # ARCHIVE-BEFORE: FOO.TXT
@@ -33,22 +32,21 @@
 
 ## Test thin archive d option with P and N modifiers (full path matching).
 
-# RUN: echo one > %t/a/file.txt
-# RUN: echo two > %t/a/FILE.txt
-# RUN: rm -f %t/archive-dPN.a
-# RUN: llvm-ar rc --thin %t/archive-dPN.a %t/a/file.txt %t/a/FILE.txt
-# RUN: llvm-ar t %t/archive-dPN.a | FileCheck %s --check-prefix=THIN-BEFORE -DPATH=%/t --implicit-check-not={{.}}
+# RUN: echo one > a/file.txt
+# RUN: echo two > a/FILE.txt
+# RUN: llvm-ar rc --thin archive-dPN.a a/file.txt a/FILE.txt
+# RUN: llvm-ar t archive-dPN.a | FileCheck %s --check-prefix=THIN-BEFORE --implicit-check-not={{.}}
 
 ## The uppercase filename occurs only once; expect no-op.
-# RUN: llvm-ar dPN 2 --thin %t/archive-dPN.a %t/a/FILE.txt
-# RUN: llvm-ar t %t/archive-dPN.a | FileCheck %s --check-prefix=THIN-BEFORE -DPATH=%/t --implicit-check-not={{.}}
+# RUN: llvm-ar dPN 2 --thin archive-dPN.a a/FILE.txt
+# RUN: llvm-ar t archive-dPN.a | FileCheck %s --check-prefix=THIN-BEFORE --implicit-check-not={{.}}
 
-# RUN: llvm-ar dPN 1 --thin %t/archive-dPN.a %t/a/FILE.txt
-# RUN: llvm-ar t %t/archive-dPN.a | FileCheck %s --check-prefix=THIN-AFTER -DPATH=%/t --implicit-check-not={{.}}
-# RUN: llvm-ar dPN 1 --thin %t/archive-dPN.a %t/a/file.txt
-# RUN: llvm-ar t %t/archive-dPN.a | count 0
+# RUN: llvm-ar dPN 1 --thin archive-dPN.a a/FILE.txt
+# RUN: llvm-ar t archive-dPN.a | FileCheck %s --check-prefix=THIN-AFTER --implicit-check-not={{.}}
+# RUN: llvm-ar dPN 1 --thin archive-dPN.a a/file.txt
+# RUN: llvm-ar t archive-dPN.a | count 0
 
-# THIN-BEFORE: [[PATH]]/a/file.txt
-# THIN-BEFORE: [[PATH]]/a/FILE.txt
+# THIN-BEFORE: a/file.txt
+# THIN-BEFORE: a/FILE.txt
 
-# THIN-AFTER: [[PATH]]/a/file.txt
+# THIN-AFTER: a/file.txt

>From cade60f6318cc9619f250dccbe0d1360b719ae98 Mon Sep 17 00:00:00 2001
From: 0xFE4415 <259395 at student.pwr.edu.pl>
Date: Thu, 28 May 2026 09:20:26 +0200
Subject: [PATCH 21/22] use mixed-case names

---
 .../llvm-ar/count-case-sensitivity-windows.test  | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/llvm/test/tools/llvm-ar/count-case-sensitivity-windows.test b/llvm/test/tools/llvm-ar/count-case-sensitivity-windows.test
index f7bd8c48589f6..2547e580aeb68 100644
--- a/llvm/test/tools/llvm-ar/count-case-sensitivity-windows.test
+++ b/llvm/test/tools/llvm-ar/count-case-sensitivity-windows.test
@@ -11,20 +11,20 @@
 # RUN: llvm-ar rc count-case.a a/foo.txt b/FOO.TXT
 
 # RUN: mkdir out1 out2
-# RUN: llvm-ar xN 1 --output out1 count-case.a foo.txt
+# RUN: llvm-ar xN 1 --output out1 count-case.a Foo.txt
 # RUN: cat out1/foo.txt | FileCheck %s --check-prefix=EXTRACT-FIRST
-# RUN: llvm-ar xN 2 --output out2 count-case.a foo.txt
+# RUN: llvm-ar xN 2 --output out2 count-case.a Foo.txt
 # RUN: cat out2/FOO.TXT | FileCheck %s --check-prefix=EXTRACT-SECOND
-# RUN: not llvm-ar xN 3 --output out2 count-case.a foo.txt 2>&1 | FileCheck %s --check-prefix=EXTRACT-NOT-FOUND
+# RUN: not llvm-ar xN 3 --output out2 count-case.a Foo.txt 2>&1 | FileCheck %s --check-prefix=EXTRACT-NOT-FOUND
 
 # EXTRACT-FIRST: first
 # EXTRACT-SECOND: second
 # EXTRACT-NOT-FOUND: error: 'foo.txt' was not found
 
 # RUN: llvm-ar rc delete-count.a a/foo.txt b/FOO.TXT
-# RUN: llvm-ar dN 2 delete-count.a foo.txt
+# RUN: llvm-ar dN 2 delete-count.a Foo.txt
 # RUN: llvm-ar t delete-count.a | FileCheck %s --check-prefix=DELETE-SECOND --implicit-check-not={{.}}
-# RUN: llvm-ar dN 1 delete-count.a FOO.TXT
+# RUN: llvm-ar dN 1 delete-count.a Foo.txt
 # RUN: llvm-ar t delete-count.a | count 0
 
 # DELETE-SECOND: foo.txt
@@ -36,12 +36,12 @@
 # RUN: llvm-ar t archive-dPN.a | FileCheck %s --check-prefix=THIN-BEFORE --implicit-check-not={{.}}
 
 ## Third does not exist; expect no-op.
-# RUN: llvm-ar dPN 3 --thin archive-dPN.a a/file.txt
+# RUN: llvm-ar dPN 3 --thin archive-dPN.a A/File.tXt
 # RUN: llvm-ar t archive-dPN.a | FileCheck %s --check-prefix=THIN-BEFORE --implicit-check-not={{.}}
 
-# RUN: llvm-ar dPN 2 --thin archive-dPN.a a/file.txt
+# RUN: llvm-ar dPN 2 --thin archive-dPN.a A/File.tXt
 # RUN: llvm-ar t archive-dPN.a | FileCheck %s --check-prefix=THIN-AFTER --implicit-check-not={{.}}
-# RUN: llvm-ar dPN 1 --thin archive-dPN.a a/file.txt
+# RUN: llvm-ar dPN 1 --thin archive-dPN.a A/File.tXt
 # RUN: llvm-ar t archive-dPN.a | count 0
 
 # THIN-BEFORE: a/file.txt

>From 967ae313fe60cec217d39ac9883a3daff11a5245 Mon Sep 17 00:00:00 2001
From: 0xFE4415 <259395 at student.pwr.edu.pl>
Date: Thu, 28 May 2026 09:28:55 +0200
Subject: [PATCH 22/22] Shows that directory case is also important

---
 llvm/test/tools/llvm-ar/count-case-sensitivity.test | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/llvm/test/tools/llvm-ar/count-case-sensitivity.test b/llvm/test/tools/llvm-ar/count-case-sensitivity.test
index f12a9b329d877..39d353a3acdb2 100644
--- a/llvm/test/tools/llvm-ar/count-case-sensitivity.test
+++ b/llvm/test/tools/llvm-ar/count-case-sensitivity.test
@@ -37,6 +37,10 @@
 # RUN: llvm-ar rc --thin archive-dPN.a a/file.txt a/FILE.txt
 # RUN: llvm-ar t archive-dPN.a | FileCheck %s --check-prefix=THIN-BEFORE --implicit-check-not={{.}}
 
+## The path to `FILE.TXT` does not match because the directory name has a different case; expect no-op.
+# RUN: llvm-ar dPN 2 --thin archive-dPN.a A/FILE.txt
+# RUN: llvm-ar t archive-dPN.a | FileCheck %s --check-prefix=THIN-BEFORE --implicit-check-not={{.}}
+
 ## The uppercase filename occurs only once; expect no-op.
 # RUN: llvm-ar dPN 2 --thin archive-dPN.a a/FILE.txt
 # RUN: llvm-ar t archive-dPN.a | FileCheck %s --check-prefix=THIN-BEFORE --implicit-check-not={{.}}



More information about the llvm-commits mailing list