Author: AZero13
Date: 2026-08-27T11:10:57+08:00
New Revision: dc222c2de55988f5359262a0e29fed5c14e824e7

URL: 
https://github.com/llvm/llvm-project/commit/dc222c2de55988f5359262a0e29fed5c14e824e7
DIFF: 
https://github.com/llvm/llvm-project/commit/dc222c2de55988f5359262a0e29fed5c14e824e7.diff

LOG: [NFC][clang][Serialization] Fix std::set_difference sorting mismatch in 
ASTReader (#219053)

Fixes a `std::set_difference` sorting violation in
`ASTReader::checkTargetOptions` that causes a crash when building clang
with `LLVM_ENABLE_EXPENSIVE_CHECKS` on libstdc++.

`accumulateFeaturesAsWritten` sorts target features using a custom
comparator that strips the `+`/`-` prefix (i.e. comparing `A.substr(1) <
B.substr(1)`). However, `std::set_difference` was being called with the
default `std::string::operator<` comparator, which does not match the
sorting order because `+` (ASCII 0x2B) is less than `-` (ASCII 0x2D).
For example, `["-cx16", "+sse2"]` is correctly sorted according to the
custom comparator, but incorrectly sorted according to the default
lexicographical comparator.

This patch fixes the issue by passing the same custom comparator used
for sorting to both `std::set_difference` calls.

Fixes #219046.

Added: 
    

Modified: 
    clang/lib/Serialization/ASTReader.cpp
    clang/test/Modules/merge-target-features.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Serialization/ASTReader.cpp 
b/clang/lib/Serialization/ASTReader.cpp
index a11e774d7bb41..b36e28819b9e1 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -525,13 +525,18 @@ static bool checkTargetOptions(const TargetOptions 
&TargetOpts,
 
   // We compute the set 
diff erence in both directions explicitly so that we can
   // diagnose the 
diff erences 
diff erently.
+  auto FeatureLess = [](StringRef A, StringRef B) {
+    return A.substr(1) < B.substr(1);
+  };
+
   SmallVector<StringRef, 4> UnmatchedExistingFeatures, UnmatchedReadFeatures;
-  std::set_
diff erence(
-      ExistingFeatures.begin(), ExistingFeatures.end(), ReadFeatures.begin(),
-      ReadFeatures.end(), std::back_inserter(UnmatchedExistingFeatures));
+  std::set_
diff erence(ExistingFeatures.begin(), ExistingFeatures.end(),
+                      ReadFeatures.begin(), ReadFeatures.end(),
+                      std::back_inserter(UnmatchedExistingFeatures),
+                      FeatureLess);
   std::set_
diff erence(ReadFeatures.begin(), ReadFeatures.end(),
                       ExistingFeatures.begin(), ExistingFeatures.end(),
-                      std::back_inserter(UnmatchedReadFeatures));
+                      std::back_inserter(UnmatchedReadFeatures), FeatureLess);
 
   // If we are allowing compatible 
diff erences and the read feature set is
   // a strict subset of the existing feature set, there is nothing to diagnose.

diff  --git a/clang/test/Modules/merge-target-features.cpp 
b/clang/test/Modules/merge-target-features.cpp
index c3678cbea11cb..f008492b7e341 100644
--- a/clang/test/Modules/merge-target-features.cpp
+++ b/clang/test/Modules/merge-target-features.cpp
@@ -148,6 +148,28 @@
 // RUN:   -fsyntax-only merge-target-features.cpp 2>&1 \
 // RUN:   | FileCheck --allow-empty --check-prefix=IGNORED2 %s
 // IGNORED2-NOT: error:
+//
+// RUN: %clang_cc1 -fmodules -x c++ -fmodules-cache-path=%t \
+// RUN:   -iquote Inputs/merge-target-features \
+// RUN:   -fno-implicit-modules \
+// RUN:   -fmodule-map-file-home-is-cwd \
+// RUN:   -emit-module -fmodule-name=foo -o %t/foo-order.pcm \
+// RUN:   -triple i386-unknown-unknown \
+// RUN:   -target-cpu i386 -target-feature -cx16 -target-feature +sse2 \
+// RUN:   Inputs/merge-target-features/module.modulemap
+//
+// RUN: not %clang_cc1 -fmodules -x c++ -fmodules-cache-path=%t \
+// RUN:   -iquote Inputs/merge-target-features \
+// RUN:   -fno-implicit-modules \
+// RUN:   -fmodule-map-file-home-is-cwd \
+// RUN:   -fmodule-map-file=Inputs/merge-target-features/module.modulemap \
+// RUN:   -fmodule-file=%t/foo-order.pcm \
+// RUN:   -triple i386-unknown-unknown \
+// RUN:   -target-cpu i386 -target-feature +sse2 \
+// RUN:   -fsyntax-only merge-target-features.cpp 2>&1 \
+// RUN:   | FileCheck --check-prefix=ORDER --implicit-check-not=error: %s
+// ORDER: error: precompiled file '{{.*}}foo-order.pcm' was compiled with the 
target feature '-cx16' but the current translation unit is not
+// ORDER: error: {{.*}} configuration mismatch
 
 #include "foo.h"
 


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

Reply via email to