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