[Analyzer][solver][NFC] print constraints deterministically (ordered by their string representation)

This change is an extension to D103967 where I added dump methods for
(dis)equality classes of the State. There, the (dis)equality classes and their
contents are dumped in an ordered fashion, they are ordered based on their
string representation. This is very useful once we start to use FileCheck to
test the State dump in certain tests.

Differential Revision: https://reviews.llvm.org/D106642
This commit is contained in:
Gabor Marton 2021-07-20 16:46:15 +02:00
parent f86694cb80
commit 4761321d49
1 changed files with 29 additions and 22 deletions

View File

@ -2630,6 +2630,13 @@ void RangeConstraintManager::printJson(raw_ostream &Out, ProgramStateRef State,
printDisequalities(Out, State, NL, Space, IsDot); printDisequalities(Out, State, NL, Space, IsDot);
} }
static std::string toString(const SymbolRef &Sym) {
std::string S;
llvm::raw_string_ostream O(S);
Sym->dumpToStream(O);
return O.str();
}
void RangeConstraintManager::printConstraints(raw_ostream &Out, void RangeConstraintManager::printConstraints(raw_ostream &Out,
ProgramStateRef State, ProgramStateRef State,
const char *NL, const char *NL,
@ -2643,25 +2650,32 @@ void RangeConstraintManager::printConstraints(raw_ostream &Out,
return; return;
} }
std::map<std::string, RangeSet> OrderedConstraints;
for (std::pair<EquivalenceClass, RangeSet> P : Constraints) {
SymbolSet ClassMembers = P.first.getClassMembers(State);
for (const SymbolRef &ClassMember : ClassMembers) {
bool insertion_took_place;
std::tie(std::ignore, insertion_took_place) =
OrderedConstraints.insert({toString(ClassMember), P.second});
assert(insertion_took_place &&
"two symbols should not have the same dump");
}
}
++Space; ++Space;
Out << '[' << NL; Out << '[' << NL;
bool First = true; bool First = true;
for (std::pair<EquivalenceClass, RangeSet> P : Constraints) { for (std::pair<std::string, RangeSet> P : OrderedConstraints) {
SymbolSet ClassMembers = P.first.getClassMembers(State); if (First) {
First = false;
// We can print the same constraint for every class member. } else {
for (SymbolRef ClassMember : ClassMembers) { Out << ',';
if (First) { Out << NL;
First = false;
} else {
Out << ',';
Out << NL;
}
Indent(Out, Space, IsDot)
<< "{ \"symbol\": \"" << ClassMember << "\", \"range\": \"";
P.second.dump(Out);
Out << "\" }";
} }
Indent(Out, Space, IsDot)
<< "{ \"symbol\": \"" << P.first << "\", \"range\": \"";
P.second.dump(Out);
Out << "\" }";
} }
Out << NL; Out << NL;
@ -2669,13 +2683,6 @@ void RangeConstraintManager::printConstraints(raw_ostream &Out,
Indent(Out, Space, IsDot) << "]," << NL; Indent(Out, Space, IsDot) << "]," << NL;
} }
static std::string toString(const SymbolRef &Sym) {
std::string S;
llvm::raw_string_ostream O(S);
Sym->dumpToStream(O);
return O.str();
}
static std::string toString(ProgramStateRef State, EquivalenceClass Class) { static std::string toString(ProgramStateRef State, EquivalenceClass Class) {
SymbolSet ClassMembers = Class.getClassMembers(State); SymbolSet ClassMembers = Class.getClassMembers(State);
llvm::SmallVector<SymbolRef, 8> ClassMembersSorted(ClassMembers.begin(), llvm::SmallVector<SymbolRef, 8> ClassMembersSorted(ClassMembers.begin(),