erikdesjardins created this revision.
Herald added subscribers: manas, ASDenysPetrov, dkrupp, donat.nagy, Szelethus, 
a.sidorin, mgrang, baloghadamsoftware.
Herald added a project: All.
erikdesjardins requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

I am working on another patch that changes StringMap's hash function,
which changes the iteration order here, and breaks some tests,
specifically:

  clang/test/Analysis/NSString.m
  clang/test/Analysis/shallow-mode.m

with errors like:

  generated arguments do not match in round-trip
  generated arguments #1 in round-trip: <...> "-analyzer-config" "ipa=inlining" 
"-analyzer-config" "max-nodes=75000" <...>
  generated arguments #2 in round-trip: <...> "-analyzer-config" 
"max-nodes=75000" "-analyzer-config" "ipa=inlining" <...>

To avoid this, sort the options by key, instead of using the default map
iteration order.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D142861

Files:
  clang/lib/Frontend/CompilerInvocation.cpp


Index: clang/lib/Frontend/CompilerInvocation.cpp
===================================================================
--- clang/lib/Frontend/CompilerInvocation.cpp
+++ clang/lib/Frontend/CompilerInvocation.cpp
@@ -877,14 +877,25 @@
   AnalyzerOptions ConfigOpts;
   parseAnalyzerConfigs(ConfigOpts, nullptr);
 
+  // Sort options by key to avoid relying on StringMap iteration order.
+  SmallVector<std::tuple<llvm::StringRef, std::string>, 4> SortedConfigOpts;
   for (const auto &C : Opts.Config) {
+    SortedConfigOpts.emplace_back(C.getKey(), C.getValue());
+  }
+  llvm::sort(SortedConfigOpts, [](const auto &A, const auto &B) {
+    return std::get<0>(A) < std::get<0>(B);
+  });
+
+  for (const auto &C : SortedConfigOpts) {
+    const llvm::StringRef &Key = std::get<0>(C);
+    const std::string &Value = std::get<1>(C);
     // Don't generate anything that came from parseAnalyzerConfigs. It would be
     // redundant and may not be valid on the command line.
-    auto Entry = ConfigOpts.Config.find(C.getKey());
-    if (Entry != ConfigOpts.Config.end() && Entry->getValue() == C.getValue())
+    auto Entry = ConfigOpts.Config.find(Key);
+    if (Entry != ConfigOpts.Config.end() && Entry->getValue() == Value)
       continue;
 
-    GenerateArg(Args, OPT_analyzer_config, C.getKey() + "=" + C.getValue(), 
SA);
+    GenerateArg(Args, OPT_analyzer_config, Key + "=" + Value, SA);
   }
 
   // Nothing to generate for FullCompilerInvocation.


Index: clang/lib/Frontend/CompilerInvocation.cpp
===================================================================
--- clang/lib/Frontend/CompilerInvocation.cpp
+++ clang/lib/Frontend/CompilerInvocation.cpp
@@ -877,14 +877,25 @@
   AnalyzerOptions ConfigOpts;
   parseAnalyzerConfigs(ConfigOpts, nullptr);
 
+  // Sort options by key to avoid relying on StringMap iteration order.
+  SmallVector<std::tuple<llvm::StringRef, std::string>, 4> SortedConfigOpts;
   for (const auto &C : Opts.Config) {
+    SortedConfigOpts.emplace_back(C.getKey(), C.getValue());
+  }
+  llvm::sort(SortedConfigOpts, [](const auto &A, const auto &B) {
+    return std::get<0>(A) < std::get<0>(B);
+  });
+
+  for (const auto &C : SortedConfigOpts) {
+    const llvm::StringRef &Key = std::get<0>(C);
+    const std::string &Value = std::get<1>(C);
     // Don't generate anything that came from parseAnalyzerConfigs. It would be
     // redundant and may not be valid on the command line.
-    auto Entry = ConfigOpts.Config.find(C.getKey());
-    if (Entry != ConfigOpts.Config.end() && Entry->getValue() == C.getValue())
+    auto Entry = ConfigOpts.Config.find(Key);
+    if (Entry != ConfigOpts.Config.end() && Entry->getValue() == Value)
       continue;
 
-    GenerateArg(Args, OPT_analyzer_config, C.getKey() + "=" + C.getValue(), SA);
+    GenerateArg(Args, OPT_analyzer_config, Key + "=" + Value, SA);
   }
 
   // Nothing to generate for FullCompilerInvocation.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to