[clang] [clang] Fix sorting module headers (PR #73146)

Tulio Magno Quites Machado Filho via cfe-commits cfe-commits at lists.llvm.org
Wed Nov 22 09:33:14 PST 2023


https://github.com/tuliom updated https://github.com/llvm/llvm-project/pull/73146

>From d0a86b80256a45bfdee790a7aec5a48d2d71e6bb Mon Sep 17 00:00:00 2001
From: Tulio Magno Quites Machado Filho <tuliom at redhat.com>
Date: Wed, 22 Nov 2023 14:01:24 -0300
Subject: [PATCH 1/2] [clang] Fix sorting module headers

Struct Module::Header is not a POD type. As such, qsort() and
llvm::array_pod_sort() must not be used to sort it. This became an issue
with the new implementation of qsort() in glibc 2.39 that is not
guaranteed to be a stable sort, causing Headers to be re-ordered and
corrupted.

Replace the usage of llvm::array_pod_sort() with std::stable_sort() in
order to fix this issue.  The signature of compareModuleHeaders() has to
be modified.

This commit also fixes commit d3676d4b666ead794fc58bbc7e07aa406dcf487a
that caused all headers to have NameAsWritten set to a 0-length string
without adapting compareModuleHeaders() to the new field.

Fixes #73145.
---
 clang/lib/Lex/ModuleMap.cpp | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/clang/lib/Lex/ModuleMap.cpp b/clang/lib/Lex/ModuleMap.cpp
index 00e13c9be4a7d73..7ba5a5f8cbf973d 100644
--- a/clang/lib/Lex/ModuleMap.cpp
+++ b/clang/lib/Lex/ModuleMap.cpp
@@ -2509,9 +2509,11 @@ void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
       << FixItHint::CreateReplacement(CurrModuleDeclLoc, "framework module");
 }
 
-static int compareModuleHeaders(const Module::Header *A,
-                                const Module::Header *B) {
-  return A->NameAsWritten.compare(B->NameAsWritten);
+static bool compareModuleHeaders(const Module::Header &A,
+                                const Module::Header &B) {
+  return A.NameAsWritten < B.NameAsWritten ||
+    (A.NameAsWritten == B.NameAsWritten &&
+     A.PathRelativeToRootModuleDirectory < B.PathRelativeToRootModuleDirectory);
 }
 
 /// Parse an umbrella directory declaration.
@@ -2574,7 +2576,7 @@ void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
     }
 
     // Sort header paths so that the pcm doesn't depend on iteration order.
-    llvm::array_pod_sort(Headers.begin(), Headers.end(), compareModuleHeaders);
+    std::stable_sort(Headers.begin(), Headers.end(), compareModuleHeaders);
 
     for (auto &Header : Headers)
       Map.addHeader(ActiveModule, std::move(Header), ModuleMap::TextualHeader);

>From 6e2e45c2bfcd3846d91184a57bb2fe39fe745b25 Mon Sep 17 00:00:00 2001
From: Tulio Magno Quites Machado Filho <tuliom at redhat.com>
Date: Wed, 22 Nov 2023 14:32:52 -0300
Subject: [PATCH 2/2] fixup! [clang] Fix sorting module headers

---
 clang/lib/Lex/ModuleMap.cpp | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/clang/lib/Lex/ModuleMap.cpp b/clang/lib/Lex/ModuleMap.cpp
index 7ba5a5f8cbf973d..591bd97075b87a9 100644
--- a/clang/lib/Lex/ModuleMap.cpp
+++ b/clang/lib/Lex/ModuleMap.cpp
@@ -2510,10 +2510,11 @@ void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
 }
 
 static bool compareModuleHeaders(const Module::Header &A,
-                                const Module::Header &B) {
+                                 const Module::Header &B) {
   return A.NameAsWritten < B.NameAsWritten ||
-    (A.NameAsWritten == B.NameAsWritten &&
-     A.PathRelativeToRootModuleDirectory < B.PathRelativeToRootModuleDirectory);
+         (A.NameAsWritten == B.NameAsWritten &&
+          A.PathRelativeToRootModuleDirectory <
+              B.PathRelativeToRootModuleDirectory);
 }
 
 /// Parse an umbrella directory declaration.



More information about the cfe-commits mailing list