[PATCH] D142861: [Clang] avoid relying on StringMap iteration order when roundtripping -analyzer-config

Erik Desjardins via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Sun Jan 29 19:57:51 PST 2023


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.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D142861.493187.patch
Type: text/x-patch
Size: 1455 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20230130/180302cc/attachment-0001.bin>


More information about the cfe-commits mailing list