Skip to content

Commit

Permalink
[Clang] avoid relying on StringMap iteration order when roundtripping…
Browse files Browse the repository at this point in the history
… -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
  • Loading branch information
erikdesjardins authored and jansvoboda11 committed Feb 1, 2023
1 parent aa29435 commit 06be346
Showing 1 changed file with 10 additions and 4 deletions.
14 changes: 10 additions & 4 deletions clang/lib/Frontend/CompilerInvocation.cpp
Expand Up @@ -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.
Expand Down

0 comments on commit 06be346

Please sign in to comment.