[PATCH] D103967: [Analyzer][solver] Add dump methods for (dis)equality classes.

2021-07-14 Thread Gabor Marton via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGbdf31471c76b: [Analyzer][solver] Add dump methods for 
(dis)equality classes. (authored by martong).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D103967/new/

https://reviews.llvm.org/D103967

Files:
  clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
  clang/test/Analysis/expr-inspection-printState-diseq-info.c
  clang/test/Analysis/expr-inspection-printState-eq-classes.c
  clang/test/Analysis/expr-inspection.c

Index: clang/test/Analysis/expr-inspection.c
===
--- clang/test/Analysis/expr-inspection.c
+++ clang/test/Analysis/expr-inspection.c
@@ -38,6 +38,8 @@
 // CHECK-NEXT:   "constraints": [
 // CHECK-NEXT: { "symbol": "reg_$0", "range": "{ [-2147483648, 13] }" }
 // CHECK-NEXT:   ],
+// CHECK-NEXT:   "equivalence_classes": null,
+// CHECK-NEXT:   "disequality_info": null,
 // CHECK-NEXT:   "dynamic_types": null,
 // CHECK-NEXT:   "dynamic_casts": null,
 // CHECK-NEXT:   "constructing_objects": null,
Index: clang/test/Analysis/expr-inspection-printState-eq-classes.c
===
--- /dev/null
+++ clang/test/Analysis/expr-inspection-printState-eq-classes.c
@@ -0,0 +1,21 @@
+// RUN: %clang_analyze_cc1 \
+// RUN:  -analyzer-checker=debug.ExprInspection %s 2>&1 | FileCheck %s
+
+void clang_analyzer_printState();
+
+void test_equivalence_classes(int a, int b, int c, int d) {
+  if (a + b != c)
+return;
+  if (a != d)
+return;
+  if (b != 0)
+return;
+  clang_analyzer_printState();
+  (void)(a * b * c * d);
+  return;
+}
+
+  // CHECK:  "equivalence_classes": [
+  // CHECK-NEXT:   [ "((reg_$0) + (reg_$1)) != (reg_$2)", "(reg_$0) != (reg_$2)" ],
+  // CHECK-NEXT:   [ "(reg_$0) + (reg_$1)", "reg_$0", "reg_$2", "reg_$3" ]
+  // CHECK-NEXT: ],
Index: clang/test/Analysis/expr-inspection-printState-diseq-info.c
===
--- /dev/null
+++ clang/test/Analysis/expr-inspection-printState-diseq-info.c
@@ -0,0 +1,34 @@
+// RUN: %clang_analyze_cc1 \
+// RUN:  -analyzer-checker=debug.ExprInspection %s 2>&1 | FileCheck %s
+
+void clang_analyzer_printState();
+
+void test_disequality_info(int e0, int b0, int b1, int c0) {
+  int e1 = e0 - b0;
+  if (b0 == 2) {
+int e2 = e1 - b1;
+if (e2 > 0) {
+  if (b1 != c0)
+clang_analyzer_printState();
+}
+  }
+}
+
+ // CHECK:"disequality_info": [
+ // CHECK-NEXT: {
+ // CHECK-NEXT:   "class": [ "(reg_$0) - 2" ],
+ // CHECK-NEXT:   "disequal_to": [
+ // CHECK-NEXT: [ "reg_$2" ]]
+ // CHECK-NEXT: },
+ // CHECK-NEXT: {
+ // CHECK-NEXT:   "class": [ "reg_$2" ],
+ // CHECK-NEXT:   "disequal_to": [
+ // CHECK-NEXT: [ "(reg_$0) - 2" ],
+ // CHECK-NEXT: [ "reg_$3" ]]
+ // CHECK-NEXT: },
+ // CHECK-NEXT: {
+ // CHECK-NEXT:   "class": [ "reg_$3" ],
+ // CHECK-NEXT:   "disequal_to": [
+ // CHECK-NEXT: [ "reg_$2" ]]
+ // CHECK-NEXT: }
+ // CHECK-NEXT:   ],
Index: clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
===
--- clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
+++ clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
@@ -592,6 +592,11 @@
   RangeSet::Factory ,
   ProgramStateRef State);
 
+  void dumpToStream(ProgramStateRef State, raw_ostream ) const;
+  LLVM_DUMP_METHOD void dump(ProgramStateRef State) const {
+dumpToStream(State, llvm::errs());
+  }
+
   /// Check equivalence data for consistency.
   LLVM_NODISCARD LLVM_ATTRIBUTE_UNUSED static bool
   isClassDataConsistent(ProgramStateRef State);
@@ -1599,6 +1604,15 @@
 
   void printJson(raw_ostream , ProgramStateRef State, const char *NL = "\n",
  unsigned int Space = 0, bool IsDot = false) const override;
+  void printConstraints(raw_ostream , ProgramStateRef State,
+const char *NL = "\n", unsigned int Space = 0,
+bool IsDot = false) const;
+  void printEquivalenceClasses(raw_ostream , ProgramStateRef State,
+   const char *NL = "\n", unsigned int Space = 0,
+   bool IsDot = false) const;
+  void printDisequalities(raw_ostream , ProgramStateRef State,
+  const char *NL = "\n", unsigned int Space = 0,
+  bool IsDot = false) const;
 
   //===--===//
   // Implementation for interface from RangedConstraintManager.
@@ -1749,6 +1763,15 @@
 // EqualityClass implementation details
 //===--===//
 

[PATCH] D103967: [Analyzer][solver] Add dump methods for (dis)equality classes.

2021-07-14 Thread Gabor Marton via Phabricator via cfe-commits
martong added a comment.

In D103967#2864229 , @steakhal wrote:

> AFAICT this patch does not introduce significant overhead to the exploded 
> graph DOT dumps.
> Before the patch, an exploded graph took 12G and about 55 secs for a single 
> top-level function.
> After the patch, it increased to 13G, and the runtime remained the same as 
> expected.
>
> Which is about a 1.5 % increase in size in total. TBH I expected slightly 
> higher numbers.
>
> This benchmark was done using a release build with dumps, asserts, and 
> expensive checks.

Thanks Balázs for the benchmark, this makes me confident to commit. Hopefully 
this time the tests won't be flaky.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D103967/new/

https://reviews.llvm.org/D103967

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D103967: [Analyzer][solver] Add dump methods for (dis)equality classes.

2021-07-08 Thread Balázs Benics via Phabricator via cfe-commits
steakhal added a comment.

AFAICT this patch does not introduce significant overhead to the exploded graph 
DOT dumps.
Before the patch, an exploded graph took 12G and about 55 secs for a single 
top-level function.
After the patch, it increased to 13G, and the runtime remained the same as 
expected.

Which is about a 1.5 % increase in size in total. TBH I expected slightly 
higher numbers.

This benchmark was done using a release build with dumps, asserts, and 
expensive checks.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D103967/new/

https://reviews.llvm.org/D103967

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D103967: [Analyzer][solver] Add dump methods for (dis)equality classes.

2021-07-05 Thread Gabor Marton via Phabricator via cfe-commits
martong updated this revision to Diff 356504.
martong added a comment.

- Use std::set for ordering


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D103967/new/

https://reviews.llvm.org/D103967

Files:
  clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
  clang/test/Analysis/expr-inspection-printState-diseq-info.c
  clang/test/Analysis/expr-inspection-printState-eq-classes.c
  clang/test/Analysis/expr-inspection.c

Index: clang/test/Analysis/expr-inspection.c
===
--- clang/test/Analysis/expr-inspection.c
+++ clang/test/Analysis/expr-inspection.c
@@ -38,6 +38,8 @@
 // CHECK-NEXT:   "constraints": [
 // CHECK-NEXT: { "symbol": "reg_$0", "range": "{ [-2147483648, 13] }" }
 // CHECK-NEXT:   ],
+// CHECK-NEXT:   "equivalence_classes": null,
+// CHECK-NEXT:   "disequality_info": null,
 // CHECK-NEXT:   "dynamic_types": null,
 // CHECK-NEXT:   "dynamic_casts": null,
 // CHECK-NEXT:   "constructing_objects": null,
Index: clang/test/Analysis/expr-inspection-printState-eq-classes.c
===
--- /dev/null
+++ clang/test/Analysis/expr-inspection-printState-eq-classes.c
@@ -0,0 +1,21 @@
+// RUN: %clang_analyze_cc1 \
+// RUN:  -analyzer-checker=debug.ExprInspection %s 2>&1 | FileCheck %s
+
+void clang_analyzer_printState();
+
+void test_equivalence_classes(int a, int b, int c, int d) {
+  if (a + b != c)
+return;
+  if (a != d)
+return;
+  if (b != 0)
+return;
+  clang_analyzer_printState();
+  (void)(a * b * c * d);
+  return;
+}
+
+  // CHECK:  "equivalence_classes": [
+  // CHECK-NEXT:   [ "((reg_$0) + (reg_$1)) != (reg_$2)", "(reg_$0) != (reg_$2)" ],
+  // CHECK-NEXT:   [ "(reg_$0) + (reg_$1)", "reg_$0", "reg_$2", "reg_$3" ]
+  // CHECK-NEXT: ],
Index: clang/test/Analysis/expr-inspection-printState-diseq-info.c
===
--- /dev/null
+++ clang/test/Analysis/expr-inspection-printState-diseq-info.c
@@ -0,0 +1,34 @@
+// RUN: %clang_analyze_cc1 \
+// RUN:  -analyzer-checker=debug.ExprInspection %s 2>&1 | FileCheck %s
+
+void clang_analyzer_printState();
+
+void test_disequality_info(int e0, int b0, int b1, int c0) {
+  int e1 = e0 - b0;
+  if (b0 == 2) {
+int e2 = e1 - b1;
+if (e2 > 0) {
+  if (b1 != c0)
+clang_analyzer_printState();
+}
+  }
+}
+
+ // CHECK:"disequality_info": [
+ // CHECK-NEXT: {
+ // CHECK-NEXT:   "class": [ "(reg_$0) - 2" ],
+ // CHECK-NEXT:   "disequal_to": [
+ // CHECK-NEXT: [ "reg_$2" ]]
+ // CHECK-NEXT: },
+ // CHECK-NEXT: {
+ // CHECK-NEXT:   "class": [ "reg_$2" ],
+ // CHECK-NEXT:   "disequal_to": [
+ // CHECK-NEXT: [ "(reg_$0) - 2" ],
+ // CHECK-NEXT: [ "reg_$3" ]]
+ // CHECK-NEXT: },
+ // CHECK-NEXT: {
+ // CHECK-NEXT:   "class": [ "reg_$3" ],
+ // CHECK-NEXT:   "disequal_to": [
+ // CHECK-NEXT: [ "reg_$2" ]]
+ // CHECK-NEXT: }
+ // CHECK-NEXT:   ],
Index: clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
===
--- clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
+++ clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
@@ -592,6 +592,11 @@
   RangeSet::Factory ,
   ProgramStateRef State);
 
+  void dumpToStream(ProgramStateRef State, raw_ostream ) const;
+  LLVM_DUMP_METHOD void dump(ProgramStateRef State) const {
+dumpToStream(State, llvm::errs());
+  }
+
   /// Check equivalence data for consistency.
   LLVM_NODISCARD LLVM_ATTRIBUTE_UNUSED static bool
   isClassDataConsistent(ProgramStateRef State);
@@ -1405,6 +1410,15 @@
 
   void printJson(raw_ostream , ProgramStateRef State, const char *NL = "\n",
  unsigned int Space = 0, bool IsDot = false) const override;
+  void printConstraints(raw_ostream , ProgramStateRef State,
+const char *NL = "\n", unsigned int Space = 0,
+bool IsDot = false) const;
+  void printEquivalenceClasses(raw_ostream , ProgramStateRef State,
+   const char *NL = "\n", unsigned int Space = 0,
+   bool IsDot = false) const;
+  void printDisequalities(raw_ostream , ProgramStateRef State,
+  const char *NL = "\n", unsigned int Space = 0,
+  bool IsDot = false) const;
 
   //===--===//
   // Implementation for interface from RangedConstraintManager.
@@ -1628,6 +1642,15 @@
 // EqualityClass implementation details
 //===--===//
 
+LLVM_DUMP_METHOD void EquivalenceClass::dumpToStream(ProgramStateRef State,
+

[PATCH] D103967: [Analyzer][solver] Add dump methods for (dis)equality classes.

2021-07-05 Thread Gabor Marton via Phabricator via cfe-commits
martong added inline comments.



Comment at: clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp:2583
+
+  llvm::SmallSet MembersStr;
+  for (std::pair ClassToSymbolSet : Members)

Ah, `SmallSet` is not sorted :( I am gonna have to change this to either 
`std::set` or to a sorted vector :(


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D103967/new/

https://reviews.llvm.org/D103967

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D103967: [Analyzer][solver] Add dump methods for (dis)equality classes.

2021-07-05 Thread Gabor Marton via Phabricator via cfe-commits
martong updated this revision to Diff 356502.
martong added a comment.
Herald added a subscriber: mgrang.

- Change the dump methods to order the equivalence classes and the disequality 
info available before printing them out


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D103967/new/

https://reviews.llvm.org/D103967

Files:
  clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
  clang/test/Analysis/expr-inspection-printState-diseq-info.c
  clang/test/Analysis/expr-inspection-printState-eq-classes.c
  clang/test/Analysis/expr-inspection.c

Index: clang/test/Analysis/expr-inspection.c
===
--- clang/test/Analysis/expr-inspection.c
+++ clang/test/Analysis/expr-inspection.c
@@ -38,6 +38,8 @@
 // CHECK-NEXT:   "constraints": [
 // CHECK-NEXT: { "symbol": "reg_$0", "range": "{ [-2147483648, 13] }" }
 // CHECK-NEXT:   ],
+// CHECK-NEXT:   "equivalence_classes": null,
+// CHECK-NEXT:   "disequality_info": null,
 // CHECK-NEXT:   "dynamic_types": null,
 // CHECK-NEXT:   "dynamic_casts": null,
 // CHECK-NEXT:   "constructing_objects": null,
Index: clang/test/Analysis/expr-inspection-printState-eq-classes.c
===
--- /dev/null
+++ clang/test/Analysis/expr-inspection-printState-eq-classes.c
@@ -0,0 +1,21 @@
+// RUN: %clang_analyze_cc1 \
+// RUN:  -analyzer-checker=debug.ExprInspection %s 2>&1 | FileCheck %s
+
+void clang_analyzer_printState();
+
+void test_equivalence_classes(int a, int b, int c, int d) {
+  if (a + b != c)
+return;
+  if (a != d)
+return;
+  if (b != 0)
+return;
+  clang_analyzer_printState();
+  (void)(a * b * c * d);
+  return;
+}
+
+ // CHECK:  "equivalence_classes": [
+ // CHECK-NEXT:   [ "(reg_$0) + (reg_$1)", "reg_$0", "reg_$2", "reg_$3" ],
+ // CHECK-NEXT:   [ "((reg_$0) + (reg_$1)) != (reg_$2)", "(reg_$0) != (reg_$2)" ]
+ // CHECK-NEXT: ],
Index: clang/test/Analysis/expr-inspection-printState-diseq-info.c
===
--- /dev/null
+++ clang/test/Analysis/expr-inspection-printState-diseq-info.c
@@ -0,0 +1,34 @@
+// RUN: %clang_analyze_cc1 \
+// RUN:  -analyzer-checker=debug.ExprInspection %s 2>&1 | FileCheck %s
+
+void clang_analyzer_printState();
+
+void test_disequality_info(int e0, int b0, int b1, int c0) {
+  int e1 = e0 - b0;
+  if (b0 == 2) {
+int e2 = e1 - b1;
+if (e2 > 0) {
+  if (b1 != c0)
+clang_analyzer_printState();
+}
+  }
+}
+
+ // CHECK:"disequality_info": [
+ // CHECK-NEXT: {
+ // CHECK-NEXT:   "class": [ "(reg_$0) - 2" ],
+ // CHECK-NEXT:   "disequal_to": [
+ // CHECK-NEXT: [ "reg_$2" ]]
+ // CHECK-NEXT: },
+ // CHECK-NEXT: {
+ // CHECK-NEXT:   "class": [ "reg_$2" ],
+ // CHECK-NEXT:   "disequal_to": [
+ // CHECK-NEXT: [ "(reg_$0) - 2" ],
+ // CHECK-NEXT: [ "reg_$3" ]]
+ // CHECK-NEXT: },
+ // CHECK-NEXT: {
+ // CHECK-NEXT:   "class": [ "reg_$3" ],
+ // CHECK-NEXT:   "disequal_to": [
+ // CHECK-NEXT: [ "reg_$2" ]]
+ // CHECK-NEXT: }
+ // CHECK-NEXT:   ],
Index: clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
===
--- clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
+++ clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
@@ -592,6 +592,11 @@
   RangeSet::Factory ,
   ProgramStateRef State);
 
+  void dumpToStream(ProgramStateRef State, raw_ostream ) const;
+  LLVM_DUMP_METHOD void dump(ProgramStateRef State) const {
+dumpToStream(State, llvm::errs());
+  }
+
   /// Check equivalence data for consistency.
   LLVM_NODISCARD LLVM_ATTRIBUTE_UNUSED static bool
   isClassDataConsistent(ProgramStateRef State);
@@ -1405,6 +1410,15 @@
 
   void printJson(raw_ostream , ProgramStateRef State, const char *NL = "\n",
  unsigned int Space = 0, bool IsDot = false) const override;
+  void printConstraints(raw_ostream , ProgramStateRef State,
+const char *NL = "\n", unsigned int Space = 0,
+bool IsDot = false) const;
+  void printEquivalenceClasses(raw_ostream , ProgramStateRef State,
+   const char *NL = "\n", unsigned int Space = 0,
+   bool IsDot = false) const;
+  void printDisequalities(raw_ostream , ProgramStateRef State,
+  const char *NL = "\n", unsigned int Space = 0,
+  bool IsDot = false) const;
 
   //===--===//
   // Implementation for interface from RangedConstraintManager.
@@ -1628,6 +1642,15 @@
 // EqualityClass implementation details
 

[PATCH] D103967: [Analyzer][solver] Add dump methods for (dis)equality classes.

2021-07-05 Thread Gabor Marton via Phabricator via cfe-commits
martong reopened this revision.
martong added a comment.
This revision is now accepted and ready to land.

I have changed the dump methods to order the equivalence classes and the 
disequality info available before printing them out. The ordering is done based 
on their string representation. This comes necessarily with some performance 
penalty, though otherwise it is impossible (or practically way too cumbersome) 
to write deterministic tests. Also, the dump is used either from the debugger 
or from small test cases or when we create an exploded graph (which is again 
intended to be used during debugging), so I think that the penalty induced by 
the sorting won't be an issue.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D103967/new/

https://reviews.llvm.org/D103967

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D103967: [Analyzer][solver] Add dump methods for (dis)equality classes.

2021-06-28 Thread Nico Weber via Phabricator via cfe-commits
thakis added a comment.

(here's another flaky failure that was due to this: 
http://45.33.8.238/mac/33008/step_7.txt )


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D103967/new/

https://reviews.llvm.org/D103967

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D103967: [Analyzer][solver] Add dump methods for (dis)equality classes.

2021-06-28 Thread Nico Weber via Phabricator via cfe-commits
thakis added a comment.

Reverted for now in d5402a2fee5d860e20378f819e200865af3a6113 



Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D103967/new/

https://reviews.llvm.org/D103967

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D103967: [Analyzer][solver] Add dump methods for (dis)equality classes.

2021-06-28 Thread Nico Weber via Phabricator via cfe-commits
thakis added a comment.

Cool, can we revert this for now then? Flakily failing on my m1 bot too: 
http://45.33.8.238/macm1/12514/step_7.txt


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D103967/new/

https://reviews.llvm.org/D103967

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D103967: [Analyzer][solver] Add dump methods for (dis)equality classes.

2021-06-28 Thread Valeriy Savchenko via Phabricator via cfe-commits
vsavchenko added a comment.

In D103967#2844140 , @thakis wrote:

> Thanks. Looks like it flakily fails on mac too every now and then: 
> http://45.33.8.238/mac/33005/step_7.txt
>
> Maybe you print something in nondeterministic iteration order?

Yes, I think that the problem is deeper.  `ClassMembers` is 
`llvm::ImmutableSet` (i.e. sorted set), and it uses `SymbolRef` (e.g. pointer 
values) for sorting.  So, it does look like the order can be nondeterministic.
However, when we print constraints, we should see similar problems, but we 
don't 樂


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D103967/new/

https://reviews.llvm.org/D103967

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D103967: [Analyzer][solver] Add dump methods for (dis)equality classes.

2021-06-28 Thread Nico Weber via Phabricator via cfe-commits
thakis added a comment.

Thanks. Looks like it flakily fails on mac too every now and then: 
http://45.33.8.238/mac/33005/step_7.txt

Maybe you print something in nondeterministic iteration order?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D103967/new/

https://reviews.llvm.org/D103967

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D103967: [Analyzer][solver] Add dump methods for (dis)equality classes.

2021-06-28 Thread Gabor Marton via Phabricator via cfe-commits
martong added a comment.

Thanks for the report @thakis ! This seems to be b/c of the different newline 
handling in windows. I've committed a change that disables the tests on windows.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D103967/new/

https://reviews.llvm.org/D103967

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D103967: [Analyzer][solver] Add dump methods for (dis)equality classes.

2021-06-28 Thread Nico Weber via Phabricator via cfe-commits
thakis added a comment.

This breaks tests on Windows: http://45.33.8.238/win/40864/step_7.txt

Please take a look, and please revert if it takes a while to fix.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D103967/new/

https://reviews.llvm.org/D103967

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D103967: [Analyzer][solver] Add dump methods for (dis)equality classes.

2021-06-28 Thread Gabor Marton via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG6f3b775c3e9c: [Analyzer][solver] Add dump methods for 
(dis)equality classes. (authored by martong).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D103967/new/

https://reviews.llvm.org/D103967

Files:
  clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
  clang/test/Analysis/expr-inspection-printState-diseq-info.c
  clang/test/Analysis/expr-inspection-printState-eq-classes.c
  clang/test/Analysis/expr-inspection.c

Index: clang/test/Analysis/expr-inspection.c
===
--- clang/test/Analysis/expr-inspection.c
+++ clang/test/Analysis/expr-inspection.c
@@ -38,6 +38,8 @@
 // CHECK-NEXT:   "constraints": [
 // CHECK-NEXT: { "symbol": "reg_$0", "range": "{ [-2147483648, 13] }" }
 // CHECK-NEXT:   ],
+// CHECK-NEXT:   "equivalence_classes": null,
+// CHECK-NEXT:   "disequality_info": null,
 // CHECK-NEXT:   "dynamic_types": null,
 // CHECK-NEXT:   "dynamic_casts": null,
 // CHECK-NEXT:   "constructing_objects": null,
Index: clang/test/Analysis/expr-inspection-printState-eq-classes.c
===
--- /dev/null
+++ clang/test/Analysis/expr-inspection-printState-eq-classes.c
@@ -0,0 +1,21 @@
+// RUN: %clang_analyze_cc1 \
+// RUN:  -analyzer-checker=debug.ExprInspection %s 2>&1 | FileCheck %s
+
+void clang_analyzer_printState();
+
+void test_equivalence_classes(int a, int b, int c, int d) {
+  if (a + b != c)
+return;
+  if (a != d)
+return;
+  if (b != 0)
+return;
+  clang_analyzer_printState();
+  (void)(a * b * c * d);
+  return;
+}
+
+// CHECK:   "equivalence_classes": [
+// CHECK-NEXT:[ "reg_$0", "(reg_$0) + (reg_$1)", "reg_$2", "reg_$3" ],
+// CHECK-NEXT:[ "((reg_$0) + (reg_$1)) != (reg_$2)", "(reg_$0) != (reg_$2)" ]
+// CHECK-NEXT:  ],
Index: clang/test/Analysis/expr-inspection-printState-diseq-info.c
===
--- /dev/null
+++ clang/test/Analysis/expr-inspection-printState-diseq-info.c
@@ -0,0 +1,34 @@
+// RUN: %clang_analyze_cc1 \
+// RUN:  -analyzer-checker=debug.ExprInspection %s 2>&1 | FileCheck %s
+
+void clang_analyzer_printState();
+
+void test_disequality_info(int e0, int b0, int b1, int c0) {
+  int e1 = e0 - b0;
+  if (b0 == 2) {
+int e2 = e1 - b1;
+if (e2 > 0) {
+  if (b1 != c0)
+clang_analyzer_printState();
+}
+  }
+}
+
+// CHECK:   "disequality_info": [
+// CHECK-NEXT:{
+// CHECK-NEXT:  "class": [ "reg_$2" ],
+// CHECK-NEXT:  "disequal_to": [
+// CHECK-NEXT:[ "(reg_$0) - 2" ],
+// CHECK-NEXT:[ "reg_$3" ]]
+// CHECK-NEXT:},
+// CHECK-NEXT:{
+// CHECK-NEXT:  "class": [ "(reg_$0) - 2" ],
+// CHECK-NEXT:  "disequal_to": [
+// CHECK-NEXT:[ "reg_$2" ]]
+// CHECK-NEXT:},
+// CHECK-NEXT:{
+// CHECK-NEXT:  "class": [ "reg_$3" ],
+// CHECK-NEXT:  "disequal_to": [
+// CHECK-NEXT:[ "reg_$2" ]]
+// CHECK-NEXT:}
+// CHECK-NEXT:  ],
Index: clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
===
--- clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
+++ clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
@@ -594,6 +594,11 @@
   RangeSet::Factory ,
   ProgramStateRef State);
 
+  void dumpToStream(ProgramStateRef State, raw_ostream ) const;
+  LLVM_DUMP_METHOD void dump(ProgramStateRef State) const {
+dumpToStream(State, llvm::errs());
+  }
+
   /// Check equivalence data for consistency.
   LLVM_NODISCARD LLVM_ATTRIBUTE_UNUSED static bool
   isClassDataConsistent(ProgramStateRef State);
@@ -1414,6 +1419,17 @@
 
   void printJson(raw_ostream , ProgramStateRef State, const char *NL = "\n",
  unsigned int Space = 0, bool IsDot = false) const override;
+  void printConstraints(raw_ostream , ProgramStateRef State,
+const char *NL = "\n", unsigned int Space = 0,
+bool IsDot = false) const;
+  void printEquivalenceClasses(raw_ostream , ProgramStateRef State,
+   const char *NL = "\n", unsigned int Space = 0,
+   bool IsDot = false) const;
+  void printEquivalenceClass(raw_ostream , ProgramStateRef State,
+ EquivalenceClass Class) const;
+  void printDisequalities(raw_ostream , ProgramStateRef State,
+  const char *NL = "\n", unsigned int Space = 0,
+  bool IsDot = false) const;
 
   //===--===//
   // Implementation for interface from RangedConstraintManager.
@@ -1637,6 +1653,15 @@
 // EqualityClass implementation details
 

[PATCH] D103967: [Analyzer][solver] Add dump methods for (dis)equality classes.

2021-06-25 Thread Valeriy Savchenko via Phabricator via cfe-commits
vsavchenko accepted this revision.
vsavchenko added a comment.
This revision is now accepted and ready to land.

Awesome, thanks!


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D103967/new/

https://reviews.llvm.org/D103967

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D103967: [Analyzer][solver] Add dump methods for (dis)equality classes.

2021-06-25 Thread Gabor Marton via Phabricator via cfe-commits
martong added a comment.

In D103967#2822287 , @steakhal wrote:

> I suspect that the exploded-graph-rewriter should be updated as well so that 
> the HTML dumps also carry this information.

I've put that into a separate patch because that change has its own complexity. 
Plus, I think this patch is meaningful and useful by itself (without the 
exploded-graph-rewriter changes).
https://reviews.llvm.org/D104917


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D103967/new/

https://reviews.llvm.org/D103967

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D103967: [Analyzer][solver] Add dump methods for (dis)equality classes.

2021-06-16 Thread Balázs Benics via Phabricator via cfe-commits
steakhal added a comment.

I suspect that the exploded-graph-rewriter should be updated as well so that 
the HTML dumps also carry this information.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D103967/new/

https://reviews.llvm.org/D103967

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D103967: [Analyzer][solver] Add dump methods for (dis)equality classes.

2021-06-16 Thread Gabor Marton via Phabricator via cfe-commits
martong added a comment.

In D103967#2809590 , @NoQ wrote:

> Yes we should definitely have as much as possible in the state dump.

Okay, I've updated likewise and added two test files to check them in 
State->dump.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D103967/new/

https://reviews.llvm.org/D103967

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D103967: [Analyzer][solver] Add dump methods for (dis)equality classes.

2021-06-16 Thread Gabor Marton via Phabricator via cfe-commits
martong updated this revision to Diff 352464.
martong added a comment.

- Extend printJson to handle equivalency info


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D103967/new/

https://reviews.llvm.org/D103967

Files:
  clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
  clang/test/Analysis/expr-inspection-printState-diseq-info.c
  clang/test/Analysis/expr-inspection-printState-eq-classes.c
  clang/test/Analysis/expr-inspection.c

Index: clang/test/Analysis/expr-inspection.c
===
--- clang/test/Analysis/expr-inspection.c
+++ clang/test/Analysis/expr-inspection.c
@@ -38,6 +38,8 @@
 // CHECK-NEXT:   "constraints": [
 // CHECK-NEXT: { "symbol": "reg_$0", "range": "{ [-2147483648, 13] }" }
 // CHECK-NEXT:   ],
+// CHECK-NEXT:   "equivalence_classes": null,
+// CHECK-NEXT:   "disequality_info": null,
 // CHECK-NEXT:   "dynamic_types": null,
 // CHECK-NEXT:   "dynamic_casts": null,
 // CHECK-NEXT:   "constructing_objects": null,
Index: clang/test/Analysis/expr-inspection-printState-eq-classes.c
===
--- /dev/null
+++ clang/test/Analysis/expr-inspection-printState-eq-classes.c
@@ -0,0 +1,21 @@
+// RUN: %clang_analyze_cc1 \
+// RUN:  -analyzer-checker=debug.ExprInspection %s 2>&1 | FileCheck %s
+
+void clang_analyzer_printState();
+
+void test_equivalence_classes(int a, int b, int c, int d) {
+  if (a + b != c)
+return;
+  if (a != d)
+return;
+  if (b != 0)
+return;
+  clang_analyzer_printState();
+  (void)(a * b * c * d);
+  return;
+}
+
+// CHECK:   "equivalence_classes": [
+// CHECK-NEXT:[ "reg_$0", "(reg_$0) + (reg_$1)", "reg_$2", "reg_$3" ],
+// CHECK-NEXT:[ "((reg_$0) + (reg_$1)) != (reg_$2)", "(reg_$0) != (reg_$2)" ]
+// CHECK-NEXT:  ],
Index: clang/test/Analysis/expr-inspection-printState-diseq-info.c
===
--- /dev/null
+++ clang/test/Analysis/expr-inspection-printState-diseq-info.c
@@ -0,0 +1,34 @@
+// RUN: %clang_analyze_cc1 \
+// RUN:  -analyzer-checker=debug.ExprInspection %s 2>&1 | FileCheck %s
+
+void clang_analyzer_printState();
+
+void test_disequality_info(int e0, int b0, int b1, int c0) {
+  int e1 = e0 - b0;
+  if (b0 == 2) {
+int e2 = e1 - b1;
+if (e2 > 0) {
+  if (b1 != c0)
+clang_analyzer_printState();
+}
+  }
+}
+
+// CHECK:   "disequality_info": [
+// CHECK-NEXT:{
+// CHECK-NEXT:  "class": [ "reg_$2" ],
+// CHECK-NEXT:  "disequal_to": [
+// CHECK-NEXT:[ "(reg_$0) - 2" ],
+// CHECK-NEXT:[ "reg_$3" ]]
+// CHECK-NEXT:},
+// CHECK-NEXT:{
+// CHECK-NEXT:  "class": [ "(reg_$0) - 2" ],
+// CHECK-NEXT:  "disequal_to": [
+// CHECK-NEXT:[ "reg_$2" ]]
+// CHECK-NEXT:},
+// CHECK-NEXT:{
+// CHECK-NEXT:  "class": [ "reg_$3" ],
+// CHECK-NEXT:  "disequal_to": [
+// CHECK-NEXT:[ "reg_$2" ]]
+// CHECK-NEXT:}
+// CHECK-NEXT:  ],
Index: clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
===
--- clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
+++ clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
@@ -594,6 +594,11 @@
   RangeSet::Factory ,
   ProgramStateRef State);
 
+  void dumpToStream(ProgramStateRef State, raw_ostream ) const;
+  LLVM_DUMP_METHOD void dump(ProgramStateRef State) const {
+dumpToStream(State, llvm::errs());
+  }
+
   /// Check equivalence data for consistency.
   LLVM_NODISCARD LLVM_ATTRIBUTE_UNUSED static bool
   isClassDataConsistent(ProgramStateRef State);
@@ -1420,6 +1425,17 @@
 
   void printJson(raw_ostream , ProgramStateRef State, const char *NL = "\n",
  unsigned int Space = 0, bool IsDot = false) const override;
+  void printConstraints(raw_ostream , ProgramStateRef State,
+const char *NL = "\n", unsigned int Space = 0,
+bool IsDot = false) const;
+  void printEquivalenceClasses(raw_ostream , ProgramStateRef State,
+   const char *NL = "\n", unsigned int Space = 0,
+   bool IsDot = false) const;
+  void printEquivalenceClass(raw_ostream , ProgramStateRef State,
+ EquivalenceClass Class) const;
+  void printDisequalities(raw_ostream , ProgramStateRef State,
+  const char *NL = "\n", unsigned int Space = 0,
+  bool IsDot = false) const;
 
   //===--===//
   // Implementation for interface from RangedConstraintManager.
@@ -1646,6 +1662,15 @@
 // EqualityClass implementation details
 //===--===//
 

[PATCH] D103967: [Analyzer][solver] Add dump methods for (dis)equality classes.

2021-06-09 Thread Artem Dergachev via Phabricator via cfe-commits
NoQ added a comment.

Yes we should definitely have as much as possible in the state dump.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D103967/new/

https://reviews.llvm.org/D103967

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D103967: [Analyzer][solver] Add dump methods for (dis)equality classes.

2021-06-09 Thread Valeriy Savchenko via Phabricator via cfe-commits
vsavchenko added a comment.

This is definitely useful!  Thanks!
I was just wondering if we should add it into the state printer instead.  @NoQ 
what's your take on this?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D103967/new/

https://reviews.llvm.org/D103967

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D103967: [Analyzer][solver] Add dump methods for (dis)equality classes.

2021-06-09 Thread Gabor Marton via Phabricator via cfe-commits
martong updated this revision to Diff 350905.
martong added a comment.

- Change comment


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D103967/new/

https://reviews.llvm.org/D103967

Files:
  clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp


Index: clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
===
--- clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
+++ clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
@@ -584,6 +584,11 @@
   LLVM_NODISCARD static inline Optional
   areEqual(ProgramStateRef State, SymbolRef First, SymbolRef Second);
 
+  void dumpToStream(ProgramStateRef State, raw_ostream ) const;
+  LLVM_DUMP_METHOD void dump(ProgramStateRef State) const {
+dumpToStream(State, llvm::errs());
+  }
+
   /// Check equivalence data for consistency.
   LLVM_NODISCARD LLVM_ATTRIBUTE_UNUSED static bool
   isClassDataConsistent(ProgramStateRef State);
@@ -640,6 +645,46 @@
   uintptr_t ID;
 };
 
+//===--===//
+// Dump functions
+//===--===//
+
+/// Dump all equivalence classes.
+LLVM_DUMP_METHOD static void dumpEqToStream(ProgramStateRef State,
+raw_ostream ) {
+  ClassMembersTy Members = State->get();
+  for (std::pair ClassToSymbolSet : Members) {
+EquivalenceClass Class = ClassToSymbolSet.first;
+Class.dumpToStream(State, os);
+os << "\n";
+  }
+}
+LLVM_DUMP_METHOD static void dumpEq(ProgramStateRef State) {
+  dumpEqToStream(State, llvm::errs());
+}
+
+/// Dump all equivalence classes along with their disequivalent classes if they
+/// have any.
+LLVM_DUMP_METHOD static void dumpDisEqToStream(ProgramStateRef State,
+   raw_ostream ) {
+  DisequalityMapTy Disequalities = State->get();
+  for (std::pair ClassToDisEqSet : Disequalities) {
+EquivalenceClass Class = ClassToDisEqSet.first;
+Class.dumpToStream(State, os);
+ClassSet DisequalClasses = ClassToDisEqSet.second;
+if (!DisequalClasses.isEmpty()) {
+  for (EquivalenceClass DisEqClass : DisequalClasses) {
+os << "DisequalTo:\n";
+DisEqClass.dumpToStream(State, os);
+  }
+}
+os << "\n";
+  }
+}
+LLVM_DUMP_METHOD static void dumpDisEq(ProgramStateRef State) {
+  dumpDisEqToStream(State, llvm::errs());
+}
+
 
//===--===//
 // Constraint functions
 
//===--===//
@@ -1589,6 +1634,15 @@
 // EqualityClass implementation details
 
//===--===//
 
+LLVM_DUMP_METHOD void EquivalenceClass::dumpToStream(ProgramStateRef State,
+ raw_ostream ) const {
+  SymbolSet ClassMembers = getClassMembers(State);
+  for (const SymbolRef  : ClassMembers) {
+MemberSym->dump();
+os << "\n";
+  }
+}
+
 inline EquivalenceClass EquivalenceClass::find(ProgramStateRef State,
SymbolRef Sym) {
   // We store far from all Symbol -> Class mappings


Index: clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
===
--- clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
+++ clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
@@ -584,6 +584,11 @@
   LLVM_NODISCARD static inline Optional
   areEqual(ProgramStateRef State, SymbolRef First, SymbolRef Second);
 
+  void dumpToStream(ProgramStateRef State, raw_ostream ) const;
+  LLVM_DUMP_METHOD void dump(ProgramStateRef State) const {
+dumpToStream(State, llvm::errs());
+  }
+
   /// Check equivalence data for consistency.
   LLVM_NODISCARD LLVM_ATTRIBUTE_UNUSED static bool
   isClassDataConsistent(ProgramStateRef State);
@@ -640,6 +645,46 @@
   uintptr_t ID;
 };
 
+//===--===//
+// Dump functions
+//===--===//
+
+/// Dump all equivalence classes.
+LLVM_DUMP_METHOD static void dumpEqToStream(ProgramStateRef State,
+raw_ostream ) {
+  ClassMembersTy Members = State->get();
+  for (std::pair ClassToSymbolSet : Members) {
+EquivalenceClass Class = ClassToSymbolSet.first;
+Class.dumpToStream(State, os);
+os << "\n";
+  }
+}
+LLVM_DUMP_METHOD static void dumpEq(ProgramStateRef State) {
+  dumpEqToStream(State, llvm::errs());
+}
+
+/// Dump all equivalence classes along with their disequivalent classes if they
+/// have any.
+LLVM_DUMP_METHOD static void 

[PATCH] D103967: [Analyzer][solver] Add dump methods for (dis)equality classes.

2021-06-09 Thread Gabor Marton via Phabricator via cfe-commits
martong created this revision.
martong added reviewers: vsavchenko, NoQ, steakhal.
Herald added subscribers: manas, ASDenysPetrov, gamesh411, dkrupp, donat.nagy, 
Szelethus, mikhail.ramalho, a.sidorin, rnkovacs, szepet, baloghadamsoftware, 
xazax.hun, whisperity.
Herald added a reviewer: Szelethus.
martong requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

This proved to be very useful during debugging.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D103967

Files:
  clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp


Index: clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
===
--- clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
+++ clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
@@ -584,6 +584,11 @@
   LLVM_NODISCARD static inline Optional
   areEqual(ProgramStateRef State, SymbolRef First, SymbolRef Second);
 
+  void dumpToStream(ProgramStateRef State, raw_ostream ) const;
+  LLVM_DUMP_METHOD void dump(ProgramStateRef State) const {
+dumpToStream(State, llvm::errs());
+  }
+
   /// Check equivalence data for consistency.
   LLVM_NODISCARD LLVM_ATTRIBUTE_UNUSED static bool
   isClassDataConsistent(ProgramStateRef State);
@@ -644,6 +649,46 @@
 // Constraint functions
 
//===--===//
 
+/// Dump all equivalence classes.
+LLVM_DUMP_METHOD static void dumpEqToStream(ProgramStateRef State,
+raw_ostream ) {
+  ClassMembersTy Members = State->get();
+  for (std::pair ClassToSymbolSet : Members) {
+EquivalenceClass Class = ClassToSymbolSet.first;
+Class.dumpToStream(State, os);
+os << "\n";
+  }
+}
+LLVM_DUMP_METHOD static void dumpEq(ProgramStateRef State) {
+  dumpEqToStream(State, llvm::errs());
+}
+
+/// Dump all equivalence classes along with their disequivalent classes if they
+/// have any.
+LLVM_DUMP_METHOD static void dumpDisEqToStream(ProgramStateRef State,
+   raw_ostream ) {
+  DisequalityMapTy Disequalities = State->get();
+  for (std::pair ClassToDisEqSet : Disequalities) {
+EquivalenceClass Class = ClassToDisEqSet.first;
+Class.dumpToStream(State, os);
+ClassSet DisequalClasses = ClassToDisEqSet.second;
+if (!DisequalClasses.isEmpty()) {
+  for (EquivalenceClass DisEqClass : DisequalClasses) {
+os << "DisequalTo:\n";
+DisEqClass.dumpToStream(State, os);
+  }
+}
+os << "\n";
+  }
+}
+LLVM_DUMP_METHOD static void dumpDisEq(ProgramStateRef State) {
+  dumpDisEqToStream(State, llvm::errs());
+}
+
+//===--===//
+// Constraint functions
+//===--===//
+
 LLVM_NODISCARD LLVM_ATTRIBUTE_UNUSED bool
 areFeasible(ConstraintRangeTy Constraints) {
   return llvm::none_of(
@@ -1589,6 +1634,15 @@
 // EqualityClass implementation details
 
//===--===//
 
+LLVM_DUMP_METHOD void EquivalenceClass::dumpToStream(ProgramStateRef State,
+ raw_ostream ) const {
+  SymbolSet ClassMembers = getClassMembers(State);
+  for (const SymbolRef  : ClassMembers) {
+MemberSym->dump();
+os << "\n";
+  }
+}
+
 inline EquivalenceClass EquivalenceClass::find(ProgramStateRef State,
SymbolRef Sym) {
   // We store far from all Symbol -> Class mappings


Index: clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
===
--- clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
+++ clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
@@ -584,6 +584,11 @@
   LLVM_NODISCARD static inline Optional
   areEqual(ProgramStateRef State, SymbolRef First, SymbolRef Second);
 
+  void dumpToStream(ProgramStateRef State, raw_ostream ) const;
+  LLVM_DUMP_METHOD void dump(ProgramStateRef State) const {
+dumpToStream(State, llvm::errs());
+  }
+
   /// Check equivalence data for consistency.
   LLVM_NODISCARD LLVM_ATTRIBUTE_UNUSED static bool
   isClassDataConsistent(ProgramStateRef State);
@@ -644,6 +649,46 @@
 // Constraint functions
 //===--===//
 
+/// Dump all equivalence classes.
+LLVM_DUMP_METHOD static void dumpEqToStream(ProgramStateRef State,
+raw_ostream ) {
+  ClassMembersTy Members = State->get();
+  for (std::pair ClassToSymbolSet : Members) {
+EquivalenceClass Class = ClassToSymbolSet.first;
+Class.dumpToStream(State, os);
+os << "\n";
+  }
+}