[PATCH] D52133: [analyzer] A testing facility for testing relationships between symbols.

2018-09-25 Thread Phabricator via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL343048: [analyzer] Add a testing facility for testing 
relationships between symbols. (authored by dergachev, committed by ).
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D52133?vs=165810=167029#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D52133

Files:
  cfe/trunk/docs/analyzer/DebugChecks.rst
  cfe/trunk/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
  cfe/trunk/test/Analysis/expr-inspection.cpp
  cfe/trunk/test/Analysis/svalbuilder-rearrange-comparisons.c

Index: cfe/trunk/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
===
--- cfe/trunk/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
@@ -43,6 +43,8 @@
   void analyzerPrintState(const CallExpr *CE, CheckerContext ) const;
   void analyzerGetExtent(const CallExpr *CE, CheckerContext ) const;
   void analyzerHashDump(const CallExpr *CE, CheckerContext ) const;
+  void analyzerDenote(const CallExpr *CE, CheckerContext ) const;
+  void analyzerExpress(const CallExpr *CE, CheckerContext ) const;
 
   typedef void (ExprInspectionChecker::*FnCheck)(const CallExpr *,
  CheckerContext ) const;
@@ -60,6 +62,7 @@
 }
 
 REGISTER_SET_WITH_PROGRAMSTATE(MarkedSymbols, SymbolRef)
+REGISTER_MAP_WITH_PROGRAMSTATE(DenotedSymbols, SymbolRef, const StringLiteral *)
 
 bool ExprInspectionChecker::evalCall(const CallExpr *CE,
  CheckerContext ) const {
@@ -82,6 +85,8 @@
 .Case("clang_analyzer_numTimesReached",
   ::analyzerNumTimesReached)
 .Case("clang_analyzer_hashDump", ::analyzerHashDump)
+.Case("clang_analyzer_denote", ::analyzerDenote)
+.Case("clang_analyzer_express", ::analyzerExpress)
 .Default(nullptr);
 
   if (!Handler)
@@ -264,6 +269,13 @@
   N = BugNode;
 State = State->remove(Sym);
   }
+
+  for (auto I : State->get()) {
+SymbolRef Sym = I.first;
+if (!SymReaper.isLive(Sym))
+  State = State->remove(Sym);
+  }
+
   C.addTransition(State, N);
 }
 
@@ -295,6 +307,92 @@
   reportBug(HashContent, C);
 }
 
+void ExprInspectionChecker::analyzerDenote(const CallExpr *CE,
+   CheckerContext ) const {
+  if (CE->getNumArgs() < 2) {
+reportBug("clang_analyzer_denote() requires a symbol and a string literal",
+  C);
+return;
+  }
+
+  SymbolRef Sym = C.getSVal(CE->getArg(0)).getAsSymbol();
+  if (!Sym) {
+reportBug("Not a symbol", C);
+return;
+  }
+
+  if (!isa(Sym)) {
+reportBug("Not an atomic symbol", C);
+return;
+  }
+
+  const auto *E = dyn_cast(CE->getArg(1)->IgnoreParenCasts());
+  if (!E) {
+reportBug("Not a string literal", C);
+return;
+  }
+
+  ProgramStateRef State = C.getState();
+
+  C.addTransition(C.getState()->set(Sym, E));
+}
+
+class SymbolExpressor
+: public SymExprVisitor> {
+  ProgramStateRef State;
+
+public:
+  SymbolExpressor(ProgramStateRef State) : State(State) {}
+
+  Optional VisitSymExpr(const SymExpr *S) {
+if (const StringLiteral *const *SLPtr = State->get(S)) {
+  const StringLiteral *SL = *SLPtr;
+  return std::string(SL->getBytes());
+}
+return None;
+  }
+
+  Optional VisitSymIntExpr(const SymIntExpr *S) {
+if (auto Str = Visit(S->getLHS()))
+  return (*Str + " " + BinaryOperator::getOpcodeStr(S->getOpcode()) + " " +
+  std::to_string(S->getRHS().getLimitedValue()) +
+  (S->getRHS().isUnsigned() ? "U" : ""))
+  .str();
+return None;
+  }
+
+  Optional VisitSymSymExpr(const SymSymExpr *S) {
+if (auto Str1 = Visit(S->getLHS()))
+  if (auto Str2 = Visit(S->getRHS()))
+return (*Str1 + " " + BinaryOperator::getOpcodeStr(S->getOpcode()) +
+" " + *Str2).str();
+return None;
+  }
+};
+
+void ExprInspectionChecker::analyzerExpress(const CallExpr *CE,
+CheckerContext ) const {
+  if (CE->getNumArgs() == 0) {
+reportBug("clang_analyzer_express() requires a symbol", C);
+return;
+  }
+
+  SymbolRef Sym = C.getSVal(CE->getArg(0)).getAsSymbol();
+  if (!Sym) {
+reportBug("Not a symbol", C);
+return;
+  }
+
+  SymbolExpressor V(C.getState());
+  auto Str = V.Visit(Sym);
+  if (!Str) {
+reportBug("Unable to express", C);
+return;
+  }
+
+  reportBug(*Str, C);
+}
+
 void ento::registerExprInspectionChecker(CheckerManager ) {
   Mgr.registerChecker();
 }
Index: cfe/trunk/docs/analyzer/DebugChecks.rst
===
--- cfe/trunk/docs/analyzer/DebugChecks.rst
+++ cfe/trunk/docs/analyzer/DebugChecks.rst
@@ -255,6 +255,23 @@
   clang_analyzer_hashDump(x); // expected-warning{{hashed string for x}}
 }
 
+- ``void 

[PATCH] D52133: [analyzer] A testing facility for testing relationships between symbols.

2018-09-25 Thread Phabricator via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC343048: [analyzer] Add a testing facility for testing 
relationships between symbols. (authored by dergachev, committed by ).

Repository:
  rL LLVM

https://reviews.llvm.org/D52133

Files:
  docs/analyzer/DebugChecks.rst
  lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
  test/Analysis/expr-inspection.cpp
  test/Analysis/svalbuilder-rearrange-comparisons.c

Index: docs/analyzer/DebugChecks.rst
===
--- docs/analyzer/DebugChecks.rst
+++ docs/analyzer/DebugChecks.rst
@@ -255,6 +255,23 @@
   clang_analyzer_hashDump(x); // expected-warning{{hashed string for x}}
 }
 
+- ``void clang_analyzer_denote(int, const char *);``
+
+  Denotes symbols with strings. A subsequent call to clang_analyzer_express()
+  will expresses another symbol in terms of these string. Useful for testing
+  relationships between different symbols.
+
+  Example usage::
+
+void foo(int x) {
+  clang_analyzer_denote(x, "$x");
+  clang_analyzer_express(x + 1); // expected-warning{{$x + 1}}
+}
+
+- ``void clang_analyzer_express(int);``
+
+  See clang_analyzer_denote().
+
 Statistics
 ==
 
Index: test/Analysis/svalbuilder-rearrange-comparisons.c
===
--- test/Analysis/svalbuilder-rearrange-comparisons.c
+++ test/Analysis/svalbuilder-rearrange-comparisons.c
@@ -1,10 +1,8 @@
 // RUN: %clang_analyze_cc1 -analyzer-checker=debug.ExprInspection,core.builtin -analyzer-config aggressive-binary-operation-simplification=true -verify -analyzer-config eagerly-assume=false %s
 
-// Temporary xfailing, as debug printing functionality has changed.
-// XFAIL: *
-
-void clang_analyzer_dump(int x);
 void clang_analyzer_eval(int x);
+void clang_analyzer_denote(int x, const char *literal);
+void clang_analyzer_express(int x);
 
 void exit(int);
 
@@ -29,907 +27,951 @@
 
 void compare_different_symbol_equal() {
   int x = f(), y = f();
-  clang_analyzer_dump(x); // expected-warning{{conj_$2{int}}}
-  clang_analyzer_dump(y); // expected-warning{{conj_$9{int}}}
-  clang_analyzer_dump(x == y);
-  // expected-warning@-1{{((conj_$2{int}) - (conj_$9{int})) == 0}}
+  clang_analyzer_denote(x, "$x");
+  clang_analyzer_denote(y, "$y");
+  clang_analyzer_express(x == y); // expected-warning {{$x - $y == 0}}
 }
 
 void compare_different_symbol_plus_left_int_equal() {
-  int x = f()+1, y = f();
-  clang_analyzer_dump(x); // expected-warning{{(conj_$2{int}) + 1}}
-  clang_analyzer_dump(y); // expected-warning{{conj_$9{int}}}
-  clang_analyzer_dump(x == y);
-  // expected-warning@-1{{((conj_$9{int}) - (conj_$2{int})) == 1}}
+  int x = f(), y = f();
+  clang_analyzer_denote(x, "$x");
+  clang_analyzer_denote(y, "$y");
+  x += 1;
+  clang_analyzer_express(x == y); // expected-warning {{$y - $x == 1}}
 }
 
 void compare_different_symbol_minus_left_int_equal() {
-  int x = f()-1, y = f();
-  clang_analyzer_dump(x); // expected-warning{{(conj_$2{int}) - 1}}
-  clang_analyzer_dump(y); // expected-warning{{conj_$9{int}}}
-  clang_analyzer_dump(x == y);
-  // expected-warning@-1{{((conj_$2{int}) - (conj_$9{int})) == 1}}
+  int x = f(), y = f();
+  clang_analyzer_denote(x, "$x");
+  clang_analyzer_denote(y, "$y");
+  x -= 1;
+  clang_analyzer_express(x == y); // expected-warning {{$x - $y == 1}}
 }
 
 void compare_different_symbol_plus_right_int_equal() {
-  int x = f(), y = f()+2;
-  clang_analyzer_dump(x); // expected-warning{{conj_$2{int}}}
-  clang_analyzer_dump(y); // expected-warning{{(conj_$9{int}) + 2}}
-  clang_analyzer_dump(x == y);
-  // expected-warning@-1{{((conj_$2{int}) - (conj_$9{int})) == 2}}
+  int x = f(), y = f();
+  clang_analyzer_denote(x, "$x");
+  clang_analyzer_denote(y, "$y");
+  y += 2;
+  clang_analyzer_express(y); // expected-warning {{$y + 2}}
+  clang_analyzer_express(x == y); // expected-warning {{$x - $y == 2}}
 }
 
 void compare_different_symbol_minus_right_int_equal() {
-  int x = f(), y = f()-2;
-  clang_analyzer_dump(x); // expected-warning{{conj_$2{int}}}
-  clang_analyzer_dump(y); // expected-warning{{(conj_$9{int}) - 2}}
-  clang_analyzer_dump(x == y);
-  // expected-warning@-1{{((conj_$9{int}) - (conj_$2{int})) == 2}}
+  int x = f(), y = f();
+  clang_analyzer_denote(x, "$x");
+  clang_analyzer_denote(y, "$y");
+  y -= 2;
+  clang_analyzer_express(y); // expected-warning {{$y - 2}}
+  clang_analyzer_express(x == y); // expected-warning {{$y - $x == 2}}
 }
 
 void compare_different_symbol_plus_left_plus_right_int_equal() {
-  int x = f()+2, y = f()+1;
-  clang_analyzer_dump(x); // expected-warning{{(conj_$2{int}) + 2}}
-  clang_analyzer_dump(y); // expected-warning{{(conj_$9{int}) + 1}}
-  clang_analyzer_dump(x == y);
-  // expected-warning@-1{{((conj_$9{int}) - (conj_$2{int})) == 1}}
+  int x = f(), y = f();
+  clang_analyzer_denote(x, "$x");
+  clang_analyzer_denote(y, "$y");
+  x += 2;
+  y 

[PATCH] D52133: [analyzer] A testing facility for testing relationships between symbols.

2018-09-17 Thread George Karpenkov via Phabricator via cfe-commits
george.karpenkov accepted this revision.
george.karpenkov added inline comments.
This revision is now accepted and ready to land.



Comment at: lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp:273
+
+  for (auto I : State->get()) {
+SymbolRef Sym = I.first;

Sidenote: this code fragment is so common I wonder whether we should have a 
helper/facility for that.


https://reviews.llvm.org/D52133



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


[PATCH] D52133: [analyzer] A testing facility for testing relationships between symbols.

2018-09-17 Thread Artem Dergachev via Phabricator via cfe-commits
NoQ added a comment.

Mm, i mean, that reason as good as well.


https://reviews.llvm.org/D52133



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


[PATCH] D52133: [analyzer] A testing facility for testing relationships between symbols.

2018-09-17 Thread Artem Dergachev via Phabricator via cfe-commits
NoQ marked an inline comment as done.
NoQ added a comment.

In https://reviews.llvm.org/D52133#1237312, @george.karpenkov wrote:

> @NoQ Actually I agree with @baloghadamsoftware that it makes sense to have a 
> separate test, as this functionality should be tested regardless of 
> svalbuilder-rearrange-comparisons existence.


That's why i added a spearate test.


https://reviews.llvm.org/D52133



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


[PATCH] D52133: [analyzer] A testing facility for testing relationships between symbols.

2018-09-17 Thread George Karpenkov via Phabricator via cfe-commits
george.karpenkov added a comment.

@NoQ Actually I agree with @baloghadamsoftware that it makes sense to have a 
separate test, as this functionality should be tested regardless of 
svalbuilder-rearrange-comparisons existence.


https://reviews.llvm.org/D52133



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


[PATCH] D52133: [analyzer] A testing facility for testing relationships between symbols.

2018-09-17 Thread Artem Dergachev via Phabricator via cfe-commits
NoQ marked an inline comment as done.
NoQ added a comment.

> Should not it we have its own test in `expr-inspection.c`?

This isn't usually necessary when we're testing all code paths anyway, but i 
guess it's worth it to test our sanity-check warnings.




Comment at: lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp:65
 REGISTER_SET_WITH_PROGRAMSTATE(MarkedSymbols, SymbolRef)
+REGISTER_MAP_WITH_PROGRAMSTATE(DenotedSymbols, SymbolRef, const void *)
 

baloghadamsoftware wrote:
> Why const `void *`?
Whoops, i was incorrectly recalling that it doesn't work because the respective 
type trait structures aren't defined for non-void pointers, but that must have 
been some other data structure.


https://reviews.llvm.org/D52133



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


[PATCH] D52133: [analyzer] A testing facility for testing relationships between symbols.

2018-09-17 Thread Artem Dergachev via Phabricator via cfe-commits
NoQ updated this revision to Diff 165810.
NoQ added a comment.

Address comments. Add more sanity checks and test them.


https://reviews.llvm.org/D52133

Files:
  docs/analyzer/DebugChecks.rst
  lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
  test/Analysis/expr-inspection.cpp
  test/Analysis/svalbuilder-rearrange-comparisons.c

Index: test/Analysis/svalbuilder-rearrange-comparisons.c
===
--- test/Analysis/svalbuilder-rearrange-comparisons.c
+++ test/Analysis/svalbuilder-rearrange-comparisons.c
@@ -1,10 +1,8 @@
 // RUN: %clang_analyze_cc1 -analyzer-checker=debug.ExprInspection,core.builtin -analyzer-config aggressive-binary-operation-simplification=true -verify -analyzer-config eagerly-assume=false %s
 
-// Temporary xfailing, as debug printing functionality has changed.
-// XFAIL: *
-
-void clang_analyzer_dump(int x);
 void clang_analyzer_eval(int x);
+void clang_analyzer_denote(int x, const char *literal);
+void clang_analyzer_express(int x);
 
 void exit(int);
 
@@ -29,907 +27,951 @@
 
 void compare_different_symbol_equal() {
   int x = f(), y = f();
-  clang_analyzer_dump(x); // expected-warning{{conj_$2{int}}}
-  clang_analyzer_dump(y); // expected-warning{{conj_$9{int}}}
-  clang_analyzer_dump(x == y);
-  // expected-warning@-1{{((conj_$2{int}) - (conj_$9{int})) == 0}}
+  clang_analyzer_denote(x, "$x");
+  clang_analyzer_denote(y, "$y");
+  clang_analyzer_express(x == y); // expected-warning {{$x - $y == 0}}
 }
 
 void compare_different_symbol_plus_left_int_equal() {
-  int x = f()+1, y = f();
-  clang_analyzer_dump(x); // expected-warning{{(conj_$2{int}) + 1}}
-  clang_analyzer_dump(y); // expected-warning{{conj_$9{int}}}
-  clang_analyzer_dump(x == y);
-  // expected-warning@-1{{((conj_$9{int}) - (conj_$2{int})) == 1}}
+  int x = f(), y = f();
+  clang_analyzer_denote(x, "$x");
+  clang_analyzer_denote(y, "$y");
+  x += 1;
+  clang_analyzer_express(x == y); // expected-warning {{$y - $x == 1}}
 }
 
 void compare_different_symbol_minus_left_int_equal() {
-  int x = f()-1, y = f();
-  clang_analyzer_dump(x); // expected-warning{{(conj_$2{int}) - 1}}
-  clang_analyzer_dump(y); // expected-warning{{conj_$9{int}}}
-  clang_analyzer_dump(x == y);
-  // expected-warning@-1{{((conj_$2{int}) - (conj_$9{int})) == 1}}
+  int x = f(), y = f();
+  clang_analyzer_denote(x, "$x");
+  clang_analyzer_denote(y, "$y");
+  x -= 1;
+  clang_analyzer_express(x == y); // expected-warning {{$x - $y == 1}}
 }
 
 void compare_different_symbol_plus_right_int_equal() {
-  int x = f(), y = f()+2;
-  clang_analyzer_dump(x); // expected-warning{{conj_$2{int}}}
-  clang_analyzer_dump(y); // expected-warning{{(conj_$9{int}) + 2}}
-  clang_analyzer_dump(x == y);
-  // expected-warning@-1{{((conj_$2{int}) - (conj_$9{int})) == 2}}
+  int x = f(), y = f();
+  clang_analyzer_denote(x, "$x");
+  clang_analyzer_denote(y, "$y");
+  y += 2;
+  clang_analyzer_express(y); // expected-warning {{$y + 2}}
+  clang_analyzer_express(x == y); // expected-warning {{$x - $y == 2}}
 }
 
 void compare_different_symbol_minus_right_int_equal() {
-  int x = f(), y = f()-2;
-  clang_analyzer_dump(x); // expected-warning{{conj_$2{int}}}
-  clang_analyzer_dump(y); // expected-warning{{(conj_$9{int}) - 2}}
-  clang_analyzer_dump(x == y);
-  // expected-warning@-1{{((conj_$9{int}) - (conj_$2{int})) == 2}}
+  int x = f(), y = f();
+  clang_analyzer_denote(x, "$x");
+  clang_analyzer_denote(y, "$y");
+  y -= 2;
+  clang_analyzer_express(y); // expected-warning {{$y - 2}}
+  clang_analyzer_express(x == y); // expected-warning {{$y - $x == 2}}
 }
 
 void compare_different_symbol_plus_left_plus_right_int_equal() {
-  int x = f()+2, y = f()+1;
-  clang_analyzer_dump(x); // expected-warning{{(conj_$2{int}) + 2}}
-  clang_analyzer_dump(y); // expected-warning{{(conj_$9{int}) + 1}}
-  clang_analyzer_dump(x == y);
-  // expected-warning@-1{{((conj_$9{int}) - (conj_$2{int})) == 1}}
+  int x = f(), y = f();
+  clang_analyzer_denote(x, "$x");
+  clang_analyzer_denote(y, "$y");
+  x += 2;
+  y += 1;
+  clang_analyzer_express(x); // expected-warning {{$x + 2}}
+  clang_analyzer_express(y); // expected-warning {{$y + 1}}
+  clang_analyzer_express(x == y); // expected-warning {{$y - $x == 1}}
 }
 
 void compare_different_symbol_plus_left_minus_right_int_equal() {
-  int x = f()+2, y = f()-1;
-  clang_analyzer_dump(x); // expected-warning{{(conj_$2{int}) + 2}}
-  clang_analyzer_dump(y); // expected-warning{{(conj_$9{int}) - 1}}
-  clang_analyzer_dump(x == y);
-  // expected-warning@-1{{((conj_$9{int}) - (conj_$2{int})) == 3}}
+  int x = f(), y = f();
+  clang_analyzer_denote(x, "$x");
+  clang_analyzer_denote(y, "$y");
+  x += 2;
+  y -= 1;
+  clang_analyzer_express(x); // expected-warning {{$x + 2}}
+  clang_analyzer_express(y); // expected-warning {{$y - 1}}
+  clang_analyzer_express(x == y); // expected-warning {{$y - $x == 3}}
 }
 
 void compare_different_symbol_minus_left_plus_right_int_equal() {
-  

[PATCH] D52133: [analyzer] A testing facility for testing relationships between symbols.

2018-09-17 Thread Balogh , Ádám via Phabricator via cfe-commits
baloghadamsoftware added a comment.

This looks better than using the "raw" dumps.

Should not it we have its own test in `expr-inspection.c`?




Comment at: lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp:65
 REGISTER_SET_WITH_PROGRAMSTATE(MarkedSymbols, SymbolRef)
+REGISTER_MAP_WITH_PROGRAMSTATE(DenotedSymbols, SymbolRef, const void *)
 

Why const `void *`?


Repository:
  rC Clang

https://reviews.llvm.org/D52133



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


[PATCH] D52133: [analyzer] A testing facility for testing relationships between symbols.

2018-09-14 Thread Artem Dergachev via Phabricator via cfe-commits
NoQ created this revision.
NoQ added reviewers: dcoughlin, xazax.hun, a.sidorin, george.karpenkov, szepet, 
rnkovacs, baloghadamsoftware.
Herald added subscribers: cfe-commits, Szelethus, jfb, mikhail.ramalho.

A test introduced in https://reviews.llvm.org/rC329780 was disabled in 
https://reviews.llvm.org/rC342317 for the reason explained in 
https://reviews.llvm.org/D41938?id=130403#inline-371070 - tests shouldn't test 
dump infrastructure when all they care about is how symbols relate to each 
other.

Add a new feature to ExprInspection: `clang_analyzer_denote()` and 
`clang_analyzer_explain()`. The former adds a notation to a symbol, the latter 
expresses another symbol in terms of previously denoted symbols.

It's currently a bit wonky - doesn't print parentheses and only supports 
denoting atomic symbols. But it's even more readable that way.

I also noticed that an important use case was omitted in these tests. Namely, 
tests for unsigned integer rearrangement are done with signed-type symbols 
stored in unsigned variables and we also need to test unsigned symbols stored 
in unsigned variables (and ideally also unsigned symbols stored in signed 
variables).


Repository:
  rC Clang

https://reviews.llvm.org/D52133

Files:
  docs/analyzer/DebugChecks.rst
  lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
  test/Analysis/svalbuilder-rearrange-comparisons.c

Index: test/Analysis/svalbuilder-rearrange-comparisons.c
===
--- test/Analysis/svalbuilder-rearrange-comparisons.c
+++ test/Analysis/svalbuilder-rearrange-comparisons.c
@@ -1,10 +1,8 @@
 // RUN: %clang_analyze_cc1 -analyzer-checker=debug.ExprInspection,core.builtin -analyzer-config aggressive-binary-operation-simplification=true -verify -analyzer-config eagerly-assume=false %s
 
-// Temporary xfailing, as debug printing functionality has changed.
-// XFAIL: *
-
-void clang_analyzer_dump(int x);
 void clang_analyzer_eval(int x);
+void clang_analyzer_denote(int x, const char *literal);
+void clang_analyzer_express(int x);
 
 void exit(int);
 
@@ -29,907 +27,951 @@
 
 void compare_different_symbol_equal() {
   int x = f(), y = f();
-  clang_analyzer_dump(x); // expected-warning{{conj_$2{int}}}
-  clang_analyzer_dump(y); // expected-warning{{conj_$9{int}}}
-  clang_analyzer_dump(x == y);
-  // expected-warning@-1{{((conj_$2{int}) - (conj_$9{int})) == 0}}
+  clang_analyzer_denote(x, "$x");
+  clang_analyzer_denote(y, "$y");
+  clang_analyzer_express(x == y); // expected-warning {{$x - $y == 0}}
 }
 
 void compare_different_symbol_plus_left_int_equal() {
-  int x = f()+1, y = f();
-  clang_analyzer_dump(x); // expected-warning{{(conj_$2{int}) + 1}}
-  clang_analyzer_dump(y); // expected-warning{{conj_$9{int}}}
-  clang_analyzer_dump(x == y);
-  // expected-warning@-1{{((conj_$9{int}) - (conj_$2{int})) == 1}}
+  int x = f(), y = f();
+  clang_analyzer_denote(x, "$x");
+  clang_analyzer_denote(y, "$y");
+  x += 1;
+  clang_analyzer_express(x == y); // expected-warning {{$y - $x == 1}}
 }
 
 void compare_different_symbol_minus_left_int_equal() {
-  int x = f()-1, y = f();
-  clang_analyzer_dump(x); // expected-warning{{(conj_$2{int}) - 1}}
-  clang_analyzer_dump(y); // expected-warning{{conj_$9{int}}}
-  clang_analyzer_dump(x == y);
-  // expected-warning@-1{{((conj_$2{int}) - (conj_$9{int})) == 1}}
+  int x = f(), y = f();
+  clang_analyzer_denote(x, "$x");
+  clang_analyzer_denote(y, "$y");
+  x -= 1;
+  clang_analyzer_express(x == y); // expected-warning {{$x - $y == 1}}
 }
 
 void compare_different_symbol_plus_right_int_equal() {
-  int x = f(), y = f()+2;
-  clang_analyzer_dump(x); // expected-warning{{conj_$2{int}}}
-  clang_analyzer_dump(y); // expected-warning{{(conj_$9{int}) + 2}}
-  clang_analyzer_dump(x == y);
-  // expected-warning@-1{{((conj_$2{int}) - (conj_$9{int})) == 2}}
+  int x = f(), y = f();
+  clang_analyzer_denote(x, "$x");
+  clang_analyzer_denote(y, "$y");
+  y += 2;
+  clang_analyzer_express(y); // expected-warning {{$y + 2}}
+  clang_analyzer_express(x == y); // expected-warning {{$x - $y == 2}}
 }
 
 void compare_different_symbol_minus_right_int_equal() {
-  int x = f(), y = f()-2;
-  clang_analyzer_dump(x); // expected-warning{{conj_$2{int}}}
-  clang_analyzer_dump(y); // expected-warning{{(conj_$9{int}) - 2}}
-  clang_analyzer_dump(x == y);
-  // expected-warning@-1{{((conj_$9{int}) - (conj_$2{int})) == 2}}
+  int x = f(), y = f();
+  clang_analyzer_denote(x, "$x");
+  clang_analyzer_denote(y, "$y");
+  y -= 2;
+  clang_analyzer_express(y); // expected-warning {{$y - 2}}
+  clang_analyzer_express(x == y); // expected-warning {{$y - $x == 2}}
 }
 
 void compare_different_symbol_plus_left_plus_right_int_equal() {
-  int x = f()+2, y = f()+1;
-  clang_analyzer_dump(x); // expected-warning{{(conj_$2{int}) + 2}}
-  clang_analyzer_dump(y); // expected-warning{{(conj_$9{int}) + 1}}
-  clang_analyzer_dump(x == y);
-  // expected-warning@-1{{((conj_$9{int}) -