aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Frontend/CompilerInvocation.cpp
diff options
context:
space:
mode:
authorErik Desjardins <erikdesjardinspublic@gmail.com>2023-02-01 13:46:59 -0800
committerJan Svoboda <jan_svoboda@apple.com>2023-02-01 13:54:09 -0800
commit06be346311b9341d3d11120a631263de863f937c (patch)
treec62b2b546ca9080ac70cc44bf87ef83f046c7724 /clang/lib/Frontend/CompilerInvocation.cpp
parentaa2943502cf2986948af69681d9b833614645cd0 (diff)
downloadllvm-06be346311b9341d3d11120a631263de863f937c.zip
llvm-06be346311b9341d3d11120a631263de863f937c.tar.gz
llvm-06be346311b9341d3d11120a631263de863f937c.tar.bz2
[Clang] avoid relying on StringMap iteration order when roundtripping -analyzer-config
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. Reviewed By: jansvoboda11, MaskRay Differential Revision: https://reviews.llvm.org/D142861
Diffstat (limited to 'clang/lib/Frontend/CompilerInvocation.cpp')
-rw-r--r--clang/lib/Frontend/CompilerInvocation.cpp14
1 files changed, 10 insertions, 4 deletions
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index ed483d2..1911c5d 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -877,14 +877,20 @@ static void GenerateAnalyzerArgs(AnalyzerOptions &Opts,
AnalyzerOptions ConfigOpts;
parseAnalyzerConfigs(ConfigOpts, nullptr);
- for (const auto &C : Opts.Config) {
+ // Sort options by key to avoid relying on StringMap iteration order.
+ SmallVector<std::pair<StringRef, StringRef>, 4> SortedConfigOpts;
+ for (const auto &C : Opts.Config)
+ SortedConfigOpts.emplace_back(C.getKey(), C.getValue());
+ llvm::sort(SortedConfigOpts, llvm::less_first());
+
+ for (const auto &[Key, Value] : SortedConfigOpts) {
// 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.